home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / PROGTOOL / LIB211.ZIP;1 / SCREEN.PRG < prev    next >
Encoding:
Text File  |  1993-12-14  |  141.3 KB  |  3,491 lines

  1. *-----------------------------------------------------------------------
  2. *-- Program...: SCREEN.PRG
  3. *-- Programmer: Ken Mayer (CIS: 71333,1030)
  4. *-- Date......: 08/02/1993
  5. *-- Notes.....: A few routines not left in PROC.PRG, these are not used 
  6. *-              as much by my own systems. See the file: README.TXT for 
  7. *--             details on how to use this library file.
  8. *-----------------------------------------------------------------------
  9.  
  10. FUNCTION Radio
  11. *-----------------------------------------------------------------------
  12. *-- Programmer..: Ed Lafferty (CIS: 76150,3302)
  13. *-- Date........: 06/08/1992
  14. *-- Notes.......: Routine to create and size a popup with radio buttons
  15. *--               for choosing only one of up to four options.  Pressing
  16. *--               the <Space Bar> on an option turns it on or off.
  17. *--               Pressing <Enter> chooses the selected option and 
  18. *--               leaves the routine.
  19. *-- Written for.: dBase IV, 1.1
  20. *-- Rev. History: 02/25/1992 - original procedure.
  21. *--               02/27/1992 -- Ken Mayer -- added option for color, but 
  22. *--               had to take number of choices back to 4 to do so. 
  23. *--               Minor alterations performed to add color choice ... 
  24. *--               and cleaning up after self ... (original cleared the 
  25. *--               screen first ... this version saves screen, restores 
  26. *--               back to it ...) Oh yeah, I turned it into a function,
  27. *--               rather than a procedure, as well.
  28. *-- Calls.......: CENTER                Procedure in PROC.PRG
  29. *--               SHADOW                Procedure in PROC.PRG
  30. *--               COLORBRK()            Function in PROC.PRG
  31. *-- Called by...: Any
  32. *-- Usage.......: Radio(<nULRow>,<nULCol>,<nChoice>,"<cTxt1>",;
  33. *--                        "<cTxt2>","<cTxt3>","<cTxt4>","<cTitle>",;
  34. *--                        "<cColor>")
  35. *-- Example.....: cPort = Radio(8,15,1,"LPT1","LPT2","LPT3","",;
  36. *--                         "Choose a printer port","rg+/gb,n/w,rg+/gb")
  37. *-- Returns.....: number of chosen button in nChoice
  38. *-- Parameters..: nUlrow  = upper left row of popup
  39. *--               nUlcol  = upper left column of popup
  40. *--               nChoice = default chosen button
  41. *--               cTxt1   = Text for 1st button
  42. *--               cTxt2   =  "    "  2nd   "
  43. *--               cTxt3   =  "    "  3rd   "
  44. *--               cTxt4   =  "    "  4th   "
  45. *--               cTitle  = Text for the box title
  46. *--               cColor  = Color string (i.e., "RG+/GB,N/W,RG+/GB")
  47. *-----------------------------------------------------------------------
  48.  
  49.    parameters nUlrow, nUlcol, nChoice, cTxt1, cTxt2, cTxt3, cTxt4,;
  50.               cTitle, cColor
  51.    private nHeight, nKey, nCnt, nWidth, cStr, cTxt0, cMidCol, ;
  52.               cFirstCol,cCursor
  53.    
  54.    m->cCursor = set("CURSOR")
  55.    store m->cTitle to m->cTxt0
  56.    save screen to sRadio
  57.    store 0 to m->nHeight, m->nKey, m->nCnt, m->nWidth
  58.    store m->nChoice to m->nOrig  && in case user presses <Esc> to exit ...
  59.    
  60.    *-- deal with these colors in displaying some stuff ...
  61.    m->cMidCol = colorbrk(m->cColor,2)
  62.    *-- First color (for message) is easier ...
  63.    m->cFirstCol = colorbrk(m->cColor,1)
  64.    
  65.    *-- Determine height and width of popup
  66.    do case
  67.       case len(m->cTxt4) > 0
  68.            m->nHeight = 4
  69.       case len(m->cTxt3) > 0
  70.            m->nHeight = 3
  71.       case len(m->cTxt2) > 0
  72.            m->nHeight = 2
  73.       otherwise
  74.            m->nHeight = 1
  75.    endcase
  76.    
  77.    do while m->nCnt <=m->nHeight
  78.       store "cTxt"+str(m->nCnt,1) to m->cStr
  79.       if len(&cStr.) > m->nWidth
  80.          m->nWidth = len(&cStr.)
  81.       endif
  82.       m->nCnt = m->nCnt + 1
  83.    enddo
  84.    
  85.    *-- create popup
  86.    define window wRadio from m->nULRow,m->nULCol to ;
  87.                m->nULRow+m->nHeight+3,m->nULCol+m->nWidth+9;
  88.                double color &cColor.
  89.    do center with 23,80,m->cFirstCol,"Press "+chr(24)+chr(25)+;
  90.       " <Space> to select/de-select, <Enter> to quit"
  91.    activate screen
  92.    do shadow with m->nULRow, m->nULCol, m->nULRow+m->nHeight+3, ;
  93.                   m->nULCol+m->nWidth+9
  94.    activate window wRadio
  95.    
  96.    *-- display screen
  97.    store 1 to m->nCnt
  98.    do center with 0, m->nWidth+8, "", m->cTitle
  99.    do while m->nCnt <= m->nHeight
  100.       store "cTxt"+str(m->nCnt,1) to m->cStr
  101.       @ m->nCnt+1, 2 SAY "[ ]" color &cMidCol.
  102.       @ m->nCnt+1, 6 say &cStr.
  103.       m->nCnt = m->nCnt + 1
  104.    enddo
  105.    
  106.    *-- prepare for and get nChoice
  107.    if m->nChoice > 0
  108.       store m->nChoice to m->nCnt
  109.       @m->nCnt+1,3 say "˛" color &cMidCol.
  110.    else
  111.       store 1 to m->nCnt
  112.    endif
  113.    store .F. to m->lDone
  114.    
  115.    *-- this loop processes user input ... 
  116.    do while .not. m->lDone
  117.       @ m->nCnt+1,3 say "" color &cMidCol.
  118.       m->nKey = inkey(0)
  119.       do case
  120.          case m->nKey = 27                   && Press Esc to exit
  121.             store m->nOrig to m->nChoice     && Leave at "default"
  122.             store .T. to m->lDone
  123.          case m->nKey = 13
  124.             store .T. to m->lDone
  125.          case m->nKey = 32                   && Press Enter or Space
  126.             set cursor off
  127.             if m->nChoice = m->nCnt
  128.                @ m->nCnt+1,3 say " " color &cMidCol.
  129.                store 0 to m->nChoice
  130.             else
  131.                @ m->nChoice+1,3 say " " color &cMidCol.
  132.                @ m->nCnt+1,3 say "˛" color &cMidCol.
  133.                store m->nCnt to m->nChoice
  134.             endif
  135.             set cursor on
  136.          case m->nKey = 5                    && Press up arrow
  137.             if m->nCnt > 1
  138.                m->nCnt = m->nCnt - 1
  139.             else
  140.                m->nCnt = m->nHeight
  141.             endif
  142.          case m->nKey = 24                   && Press down arrow
  143.             if m->nCnt < m->nHeight
  144.                m->nCnt = m->nCnt + 1
  145.             else
  146.                m->nCnt = 1
  147.             endif
  148.       endcase
  149.    enddo
  150.    
  151.    *-- cleanup
  152.    release window wRadio
  153.    restore screen from sRadio
  154.    release screen sRadio
  155.    set message to
  156.    set cursor &cCursor.
  157.    
  158. RETURN m->nChoice
  159. *-- EoF: Radio()
  160.  
  161. PROCEDURE CheckBox
  162. *-----------------------------------------------------------------------
  163. *-- Programmer..: Ed Lafferty (CIS: 76150,3302)
  164. *-- Date........: 04/22/1993
  165. *-- Notes.......: Routine to create and size a popup with check boxes
  166. *--               for choosing any of a number (up to five) options.  
  167. *--               Pressing the <Space Bar> on an option turns it on or 
  168. *--               off. Pressing <Enter> chooses the selected option and
  169. *--               leaves the routine. You must use a data structure with
  170. *--               logical fields, or memvars that are logical for this.
  171. *--               Either way, even if you don't use five logical fields/
  172. *--               memvars, you must pass a field/memvar to the procedure 
  173. *--               -- see Example below (the logicals -- lCHK1, lCHK2, 
  174. *--               etc.-- must be fields or memvars due to a limitation in 
  175. *--               parameter passing in dBASE IV.)
  176. *-- Written for.: dBase IV, Version 1.5+
  177. *-- Rev. History: 02/25/1992 -- Original procedure.
  178. *--               02/28/1992 -- Ken Mayer -- modified to allow passing 
  179. *--               cColor, and a little cleanup of code and such. Minor 
  180. *--               changes.
  181. *--               04/22/1993 -- Angus Scott-Fleming:
  182. *--                   Revised for 1.5:
  183. *--                   Turned cursor on
  184. *--                   Moved help-line info inside box.
  185. *--                   Reorganized parameters to allow calling
  186. *--                      with variable # of choices, and evaluate with 
  187. *--                      pCOUNT(). NOTE: If more than 9 pairs are 
  188. *--                      needed, two loops will have to be changed from 
  189. *--                      STR(NCNT,1) to lTrim STR(cCnt,2))
  190. *--                   Enabled error-trapping for poorly located boxes.
  191. *--                   Appended "." to all &Macros.
  192. *-- Calls.......: CENTER               Procedure in PROC.PRG
  193. *--               SHADOW               Procedure in PROC.PRG
  194. *--               COLORBRK()           Function in PROC.PRG
  195. *-- Called by...: Any
  196. *-- Usage.......: do checkbox with <nULCol>,<nULRow>,<cTitle>,<cColor>,;
  197. *--                          <lchk1>,<cTxt1>,[<lchk2>,<cTxt2>];
  198. *--                          [,<lchk3>,<cTxt3>][,<lchk4>,<cTxt4>];
  199. *--                          [... to 9]
  200. *-- Example.....: do Checkbox with 8, 15, "Choose a printer port",;
  201. *--                    "rg+/gb,w+/n,rg+/gb", lchk1, "LPT1", lchk2, ;
  202. *--                    "LPT2", lchk3, "LPT3"
  203. *-- Returns.....: .T. for selected items, .F. for non-selected items --
  204. *--               this routine changes the value of the logical fields 
  205. *--               passed to it.
  206. *-- Parameters..: nULRow = upper left row of popup
  207. *--               nULCol = upper left column of popup
  208. *--               cTitle = Title for box
  209. *--               cColor = Colors for window
  210. *--               lChkn  = default value of box 'n' -- MUST BE 
  211. *--                        FIELDS/MEMVARS
  212. *--               cTxtn  = Text for 'n'th box
  213. *--               cColor = Colors to be used in window ...
  214. *-----------------------------------------------------------------------
  215.  
  216.    parameters nUlrow, nUlcol, cTitle, cColor, lChk1, cTxt1, lChk2, ;
  217.          cTxt2, lChk3, cTxt3, lChk4, cTxt4, lChk5, cTxt5, lChk6,;
  218.          cTxt6, lChk7, cTxt7, lChk8, cTxt8, lChk9, cTxt9
  219.    private nHeight, nKey, nCnt, nWidth, cMidCol, cFirstCol, cCursor,;
  220.               cPrompt, nBRRow, nBRCol
  221.    
  222.    *-- setup ...
  223.    m->cCursor = set("CURSOR")
  224.    save screen to sCheck
  225.    store 0 to m->nHeight, m->nKey, m->nWidth
  226.    m->cPrompt = "Press "+chr(24)+chr(25)+;
  227.           ", <Space> to select/de-select, <Enter> to quit"
  228.       
  229.    *-- save original settings, in case <Esc> gets pressed below ...
  230.    *-- determine height/width of popup
  231.    m->nWidth  = max(len(m->cPrompt),len(m->cTitle))
  232.    m->nHeight = (pcount() - 4)/2
  233.    m->nCnt    = 0
  234.    do while m->nCnt < m->nHeight
  235.       m->nCnt = m->nCnt + 1
  236.       m->cCnt = str(m->nCnt,1)
  237.       private lOrig&cCnt.
  238.       store lChk&cCnt. to lOrig&cCnt.
  239.       m->nWidth = max(m->nWidth,len(cTxt&cCnt.))
  240.    enddo
  241.    *-- add border to window
  242.    m->nWidth = min(m->nWidth+8,79)
  243.    
  244.    *-- deal with some colors ...
  245.    m->cMidCol   = colorbrk(m->cColor,2)
  246.    m->cFirstCol = colorbrk(m->cColor,1)
  247.    
  248.    *-- create popup and trap errors defining the window
  249.    m->nBRRow = m->nULRow + m->nHeight + 5
  250.    m->nBRCol = m->nULCol + m->nWidth
  251.    if m->nBRRow > 24
  252.       *-- center window vertically
  253.       m->nULRow = max(12-(m->nHeight+5)/2,0)
  254.       m->nBRRow = min(23,(m->nULRow+m->nHeight+5))
  255.    endif
  256.    if m->nBRCol > 80
  257.       *-- center window horizontally
  258.       m->nULCol = max(40 - m->nWidth/2,0)
  259.       m->nBRCol = min(79,(m->nULCol+m->nWidth))
  260.    endif
  261.    
  262.    define window wCheck from m->nULRow, m->nULCol to m->nBRRow, ;
  263.                              m->nBRCol double color &cColor.
  264.    activate screen
  265.    do shadow with m->nULRow,m->nULCol,m->nBRRow,m->nBRCol
  266.    activate window wCheck
  267.    
  268.    *-- paint screen
  269.    do center with 0,m->nWidth,"",m->cTitle
  270.    store 1 to m->nCnt
  271.    do while m->nCnt <= m->nHeight
  272.       store "cTxt"+str(m->nCnt,1) to m->cStr
  273.       store "lChk"+str(m->nCnt,1) to m->cChk
  274.       @m->nCnt+1,2 say "["+iif(&cChk.,"X"," ")+"]" color &cMidCol.
  275.       @m->nCnt+1,6 say left(&cStr.,m->nWidth-9)
  276.       m->nCnt = m->nCnt + 1
  277.    enddo
  278.    do center with m->nCnt+2,m->nWidth,"",m->cPrompt
  279.       
  280.    *-- prepare for and get nChoice
  281.    store 1 to m->nCnt
  282.    store .F. to m->lDone
  283.    do while .not. m->lDone
  284.       store "lChk"+str(m->nCnt,1) to m->cChk
  285.       @ m->nCnt+1,3 say "" color &cMidCol.
  286.       nkey = inkey(0)
  287.       do case
  288.          case m->nKey = 27                   && Press Esc to exit
  289.             m->nCnt = 0
  290.             do while m->nCnt < m->nHeight
  291.                m->nCnt = m->nCnt + 1
  292.                m->cCnt = str(m->nCnt,1)
  293.                store lOrig&cCnt. to lChk&cCnt.
  294.             enddo
  295.             store .T. to m->lDone
  296.          case m->nKey = 13                && Press Enter when finished
  297.             store .T. to m->lDone
  298.          case m->nKey = 32                && Press Space
  299.           set cursor off       
  300.           if &cChk.                  && Box was already selected,
  301.              @ m->nCnt+1,3 say " " color &cMidCol.  
  302.                                 && so now de-select it
  303.                   store .F. to &cChk.
  304.                else                     && Box was not already selected,
  305.                   @ m->nCnt+1,3 say "X" color &cMidCol.  
  306.                               && so now select it
  307.                   store .T. to &cChk.
  308.                endif
  309.                set cursor on
  310.          case m->nKey = 5                 && Press up arrow
  311.             if m->nCnt > 1
  312.                m->nCnt = m->nCnt - 1
  313.             else
  314.                m->nCnt = m->nHeight
  315.             endif
  316.          case m->nKey = 24                && Press down arrow
  317.             if m->nCnt < m->nHeight
  318.                m->nCnt = m->nCnt + 1
  319.             else
  320.                m->nCnt = 1
  321.             endif
  322.       endcase
  323.    enddo
  324.    
  325.    *-- Cleanup
  326.    release window wCheck
  327.    restore screen from sCheck
  328.    release screen sCheck
  329.    set message to
  330.    set cursor &cCursor.
  331.    
  332. RETURN
  333. *-- EoP: ChkBox
  334.  
  335. FUNCTION MenuPad
  336. *-----------------------------------------------------------------------
  337. *-- Programmer..: Douglas P. Saine (CIS: 74660,3574)
  338. *-- Date........: 02/11/1992
  339. *-- Notes.......: Used to create menu prompts of an even length. It 
  340. *--               works on any prompt - menu pads or popups.
  341. *-- Written for.: dBASE IV, 1.1
  342. *-- Rev. History: 02/07/1992 - original function.
  343. *--               02/11/1992 -- Ken Mayer -- modified to truncate 
  344. *--                 <cChoice> if it's longer than <nLength>.
  345. *-- Calls.......: ALLTRIM()            Function in PROC.PRG
  346. *-- Called by...: Any
  347. *-- Usage.......: MenuPad("<cChoice>",<nLength>)
  348. *-- Example.....: Define pad pPad1 of mMain;
  349. *--                      prompt MenuPad("Menu Choice1",25) at 2,5
  350. *-- Returns.....: <cChoice> padded with spaces (or truncated, if 
  351. *--                    necessary) to <nLength>.
  352. *-- Parameters..: cChoice = Menu-Pad/Popup-Bar Prompt description
  353. *--               nLength = Length of pad/bar ...
  354. *-----------------------------------------------------------------------
  355.  
  356.    parameters cChoice, nLength
  357.    private cReturn
  358.    
  359.    if len(alltrim(m->cChoice)) > m->nLength  && is it too long?
  360.       m->cReturn = left(m->cChoice,m->nLength)  && truncate it ...
  361.    else         && otherwise, pad it with spaces to the length required
  362.       m->cReturn = m->cChoice + space(m->nLength-;
  363.                                        len(alltrim(m->cChoice)))
  364.    endif
  365.  
  366. RETURN m->cReturn
  367. *-- EoF: MenuPad()
  368.  
  369. FUNCTION Banner
  370. *-----------------------------------------------------------------------
  371. *-- Programmer..: Dan Madoni (Borland)
  372. *-- Date........: 09/01/1991
  373. *-- Notes.......: This will display a left-scrolling message on the 
  374. *--               screen within the boundaries specified in the UDF by 
  375. *--               the user. It will wait for a keypress and then go 
  376. *--               away. Taken from TECHNOTES.
  377. *-- Written for.: dBASE IV, 1.1
  378. *-- Rev. History: 09/01/1991 -- Original
  379. *-- Usage.......: Banner(<nRow>,<nCol>,<nWidth>,"<cMessage>","<cColor>")
  380. *-- Example.....: ?? Banner(5,30,20,"Love your tie, is it new?","w+/r")
  381. *-- Returns.....: Null ("")
  382. *-- Parameters..: nRow     = Leftmost ROW position of scrolled message
  383. *--               nCol     = Leftmost COL position of scrolled message
  384. *--               nWidth   = Length of displayable area starting at 
  385. *--                          nRow,nCol
  386. *--               cMessage = Message to be scrolled
  387. *--               cColor   = Color of scrolling message
  388. *-----------------------------------------------------------------------
  389.  
  390.    parameters nRow,nCol,nWidth,cMessage,cColor
  391.    private cCursor,cTalk,cMsg,nCounter,cPause
  392.    
  393.    *-- save some environment essentials
  394.    save screen to sBanner
  395.    m->cCursor = set("CURSOR")
  396.    m->cTalk   = set("TALK")
  397.    set cursor off
  398.    set talk off
  399.    
  400.    *-- deal with message
  401.    m->cMsg = space(m->nWidth)+m->cMessage+" "
  402.    m->nCounter = 0
  403.    
  404.    *-- loop
  405.    do while .t.
  406.       m->nCounter = m->nCounter + 1
  407.       if m->nCounter > len(m->cMsg)
  408.          m->nCounter = 1
  409.       endif
  410.       
  411.       *-- user hits any key
  412.       m->nPause = inkey(.15)
  413.       if m->nPause # 0
  414.          exit
  415.       endif
  416.       
  417.       *-- display message within scrollable area
  418.       @m->nRow,m->nCol say substr(m->cMsg,m->nCounter,m->nWidth) ;
  419.                  color &cColor.
  420.    enddo
  421.    
  422.    *-- restore environment
  423.    restore screen from sBanner
  424.    release screen sBanner
  425.    set cursor &cCursor.
  426.    set talk &cTalk.
  427.  
  428. RETURN ""
  429. *-- EoF: Banner()
  430.  
  431. FUNCTION SeeMatch
  432. *-----------------------------------------------------------------------
  433. *-- Programmer..: Dan Madoni (Borland)
  434. *-- Date........: 06/12/1992
  435. *-- Notes.......: Can be included in format screen to display an instant
  436. *--               lookup match on a particular field. A shadowed box 
  437. *--               will appear with the matching value ... Taken from 
  438. *--               TECHNOTES.
  439. *-- Written for.: dBASE IV, 1.1
  440. *-- Rev. History: 09/01/1991 -- Original
  441. *--               06/12/1992 -- Minor -- added call to RECOLOR
  442. *-- Calls.......: RECOLOR              Procedure in PROC.PRG
  443. *-- Called by...: None
  444. *-- Usage.......: SeeMatch("<cFile>",<cSeekExp>,"<cReturn>",<nULRow>,;
  445. *--                        <nULCol>,<nBRRow>,<nBRCol>,"<cColor>)
  446. *-- Example.....: SeeMatch("TRAVEL",LASTNAME,"TRAVELCODE",2,40,4,60,;
  447. *--                        "w+/r")
  448. *-- Returns.....: .t.
  449. *-- Parameters..: cFile    = Database alias in which lookup will be 
  450. *--                          performed. This file must already be USEd 
  451. *--                          in some area.
  452. *--               cSeekExp = Expression which will be SEEKed.
  453. *--               cReturn  = Name of field to contain the 'return' 
  454. *--                          value.
  455. *--               nULRow   = Upper Left Row for box
  456. *--               nULCol   = Upper Left Column for box
  457. *--               nBRRow   = Bottom Right Row
  458. *--               nBRCol   = Bottom Right Column
  459. *--               cColor   = Color of box
  460. *----------------------------------------------------------------------
  461.    
  462.    parameters cFile,cSeeExp,cReturn,nULRow,nULCol,nBRRow,nBRCol,cColor
  463.    private cRetVal, cAttr, cStartFile
  464.    
  465.    *-- store starting position ...
  466.    m->cStartFile = alias()
  467.    select &cFile.
  468.    
  469.    *-- look for a matching expression
  470.    seek m->cSeekExp
  471.    if found()
  472.       m->cRetVal = &cReturn.
  473.    else
  474.       m->cRetVal = "<Not Found>"
  475.    endif
  476.    
  477.    *-- Store current color and draw a box
  478.    m->cAttr = set("ATTRIBUTES")
  479.    @m->nULRow+1,m->nULCol+1 fill to m->nBRRow+1,m->nBRCol+1;
  480.                                         color w/n  && shadow
  481.    set color to &cColor.
  482.    @m->nULRow,m->nULCol clear to m->nBRRow,m->nBRCol  && clear out area 
  483.                                                       && text will go in
  484.    @m->nULRow,m->nULCol To       m->nBRRow,m->nBRCol  && draw box
  485.    
  486.    *-- display matching expresion, and return to initial area ...
  487.    @m->nULRow+1,m->nULCol+2 say m->cRetVal
  488.    do ReColor with m->cAttr
  489.    select m->cStartFile
  490.    
  491. RETURN .t.
  492. *-- EoF: SeeMatch()
  493.  
  494. FUNCTION Dialog
  495. *-----------------------------------------------------------------------
  496. *-- Programmer..: Larry Quaglia (Borland)
  497. *-- Date........: 06/09/1992
  498. *-- Notes.......: This routine provides a 'standard' set of dialogue 
  499. *--               boxes and buttons for all applications. The concept is
  500. *--               to provide standardization for your apps. Taken from 
  501. *--               TECHNOTES.
  502. *-- Written for.: dBASE IV, 1.1
  503. *-- Rev. History: 11/01/1991 -- first published in TechNotes.
  504. *--               06/09/1992 -- Modified to handle explicit colors, 
  505. *--                             changed the color parameters a tad ... 
  506. *--                             (Ken Mayer)
  507. *-- Calls.......: SHADOW               Function in PROC.PRG
  508. *--               RECOLOR              Procedure in PROC.PRG
  509. *-- Called by...: Any
  510. *-- Usage.......: Dialog("<cMsg>",<nType>,"<cBorder>",<nDefBut>,;
  511. *--                       <lShadow>,"<cWind>","<cButton>")
  512. *-- Example.....: Dialog("We have completed the transaction.",0,;
  513. *--                      "DOUBLE",0,.t.,"RG+/GB","W+/N")
  514. *-- Returns.....: Character -- Either 'ERROR' or title of Button.
  515. *-- Parameters..: cMsg    = Message to be displayed -- maximum of 78 
  516. *--                         characters (one line only)
  517. *--               nType   = Dialogue box TYPE. Options are 0 to 5:
  518. *--                         0:   'OK'
  519. *--                         1: 'OK'  'CANCEL'
  520. *--                         2: 'ABORT'  'RETRY'  'IGNORE'
  521. *--                         3: 'YES'  'NO'  'CANCEL'
  522. *--                         4: 'YES'  'NO'
  523. *--                         5: 'RETRY' 'CANCEL'
  524. *--               cBorder = Border Style -- options are: "" (null) for
  525. *--                         SINGLE, DOUBLE or PANEL.
  526. *--               nDefBut = Default Button. 
  527. *--               lShadow = Display with a shadow or not (both on window
  528. *--                         and buttons)?
  529. *--               cWind   = Window Colors (must be valid dBASE color 
  530. *--                         combo i.e., "RG+/GB")
  531. *--               cButton = Highlighted Button Color (Same as above, 
  532. *--                         should contrast ...)
  533. *-----------------------------------------------------------------------
  534.  
  535.    parameters cMsg,nType,cBorder,nDefBut,lShadow,cWind,cButton
  536.    private nMsgLen,cNewColor,aButton,nMaxLine,nY,nBoxLen,nNumButton,;
  537.            nCounter,nBasex,nYCol,nMsgLoc,cCurColor
  538.  
  539.    save screen to sDialog         && so we can restore at end of routine
  540.    
  541.    *-- determine length of message
  542.    m->nMsgLen = len(trim(ltrim(m->cMsg))) + 1
  543.    
  544.    *-- Check for valid parms
  545.    do case
  546.       case m->nMsgLen > 78
  547.          RETURN "ERROR - Message Length"
  548.        case .not. (upper(m->cBorder) = "DOUBLE" .or. ;
  549.               upper(m->cBorder) = "PANEL" .or.;
  550.                    len(trim(m->cBorder)) = 0)
  551.          RETURN "ERROR - Border"
  552.    endcase
  553.    
  554.    *-- save current color info and set color to user-defined
  555.    m->cCurColor = set("ATTRIBUTES")
  556.    set color of normal    to &cWind.
  557.    set color of box       to &cWind.
  558.    set color of message   to &cWind.
  559.    set color of highlight to &cButton.
  560.    
  561.    *-- Allow use of <Tab> to move from button to button
  562.    on key label tab keyboard chr(4)  && act as if right arrow 
  563.                                      && were pushed
  564.    
  565.    *-- Define button array -- max of 3 buttons (at the moment)
  566.    declare aButton[3]
  567.    aButton[1] = ""
  568.    aButton[2] = ""
  569.    aButton[3] = ""
  570.    
  571.    *-- Establish screen height to properly center dialogue box
  572.    m->nMaxLine = iif(right(set("DISP"),2) = "43",43,24)
  573.    
  574.    *-- Determine length of passed "message" parameter. If long enough, 
  575.    *-- make the dialog box a little bigger. If very short, make it just 
  576.    *-- big enough to accomodate the three buttons.
  577.    m->nY = iif(int(m->nMsgLen) > 30,int(m->nMsgLen/2)+2,24)
  578.    m->nBoxLen = 2 * m->nY
  579.    
  580.    *-- Setup the window and determine if shadow ... if yes, call shadow
  581.    define window wDialog from int(m->nMaxLine/2)-5,40-m->nY to ;
  582.           int(m->nMaxLine/2)+4,40+m->nY &cBorder.
  583.    if m->lShadow
  584.       activate screen
  585.       do shadow with int(m->nMaxLine/2)-5,40-m->nY,;
  586.                      int(m->nMaxLine/2)+4,40+m->nY
  587.    endif
  588.    activate window wDialog
  589.    clear
  590.    
  591.    *-- Determine the type of buttons and set appropriate parms.
  592.    *-- These could be modified to your own needs.
  593.    do case
  594.       case m->nType = 0
  595.          m->nNumButton = 1
  596.          aButton[1] = "   OK   "
  597.       case m->nType = 1
  598.          m->nNumButton = 2
  599.          aButton[1] = "   OK   "
  600.          aButton[2] = " CANCEL "
  601.       case m->nType = 2
  602.          m->nNumButton = 3
  603.          aButton[1] = " ABORT  "
  604.          aButton[2] = " RETRY  "
  605.          aButton[3] = " IGNORE "
  606.       case m->nType = 3
  607.          m->nNumButton = 3
  608.          aButton[1] = "   YES  "
  609.          aButton[2] = "   NO   "
  610.          aButton[3] = " CANCEL "
  611.       case m->nType = 4
  612.          m->nNumButton = 2
  613.          aButton[1] = "   YES  "
  614.          aButton[2] = "   NO   "
  615.       case m->nType = 5
  616.          m->nNumButton = 2
  617.          aButton[1] = " RETRY  "
  618.          aButton[2] = " CANCEL "
  619.    endcase
  620.    
  621.    *-- Get dialog box length to create a bar menu of appropriate size.
  622.    *-- Define the bar menu in a loop. Deactivate it upon selection of
  623.    *-- one of the buttons.
  624.    m->nCounter = 1
  625.    m->nBaseX = m->nBoxLen / (m->nNumButton + 1)
  626.    define menu mDialog
  627.    do while m->nCounter <= m->nNumButton
  628.       pPadName = "PAD"+str(m->nCounter,1)  && pad name is 'PAD #'
  629.       m->nYCol = (m->nCounter * m->nBaseX) - ;
  630.                  (int(len(aButton[m->nCounter]) /2))
  631.       define pad &pPadName. of mDialog prompt aButton[m->nCounter] ;
  632.                  at 4,m->nYCol
  633.       
  634.       *-- If shadow is on, put shadows on buttons as well ...
  635.       if m->lShadow
  636.          activate screen
  637.          do shadow with 3,m->nYCol-2,5,m->nYCol+;
  638.                    (len(aButton[m->nCounter]))-1
  639.       endif
  640.       @3,m->nYCol-1 to 5,m->nYCol+(len(aButton[m->nCounter]))  
  641.                                             && box around button
  642.       on selection pad &pPadName. of mDialog deactivate menu
  643.       m->nCounter = m->nCounter + 1
  644.    enddo
  645.    
  646.    *-- place message (centered in box)
  647.    m->nMsgLoc = int(m->nBoxLen/2) - int(m->nMsgLen/2)
  648.    @1,m->nMsgLoc say m->cMsg
  649.    
  650.    *-- place cursor to the default button specified by the user
  651.    m->nCounter = 1
  652.    do while m->nCounter < m->nDefBut
  653.       keyboard chr(4)
  654.       m->nCounter = m->nCounter + 1
  655.    enddo
  656.    
  657.    *-- Activate the whole thing, and return the button name
  658.    activate menu mDialog
  659.    m->cValue = trim(ltrim(prompt()))
  660.    
  661.    *-- deactivate it all, restore screen, etc.
  662.    release window wDialog
  663.    release menu mDialog
  664.    restore screen from sDialog
  665.    release screen sDialog
  666.    do ReColor with m->cCurColor
  667.    on key label tab
  668.    
  669. RETURN m->cValue
  670. *-- EoF: Dialog()
  671.  
  672. FUNCTION MsgExp
  673. *-----------------------------------------------------------------------
  674. *-- Programmer..: Adam Menkes (Borland)
  675. *-- Date........: 02/05/1993
  676. *-- Notes.......: Allows you to display message (or error message), 
  677. *--               centered like SET MESSAGE ... with added utility. Does
  678. *--               not use "(Press Space)", which can be annoying. The 
  679. *--               message and the line on which it is displayed will be 
  680. *--               the same color. Taken from TECHNOTES. 
  681. *-- Written for.: dBASE IV, 1.1
  682. *-- Rev. History: 09/01/1991 -- Original routine
  683. *--               02/05/1993 -- Modified by Lee Hite to handle a string 
  684. *--                             that is greater than 80 characters (this
  685. *--                             can be a real problem if the message is 
  686. *--                             in row 24!)
  687. *-- Usage.......: MsgExp("<cExp>")
  688. *-- Example.....: MsgExp("This is a message")
  689. *-- Returns.....: Message displayed (centered) on screen
  690. *-- Parameters..: cExp  = Message to be displayed
  691. *-----------------------------------------------------------------------
  692.  
  693.    parameters cMsg
  694.    private nLen
  695.    
  696.    m->nLen = (80-len(trim(m->cMsg)))/2
  697.  
  698. RETURN space(m->nLen) + trim(m->cMsg) + space(m->nLen+0.5)
  699. *-- EoF: MsgExp
  700.  
  701. FUNCTION YesNoCan
  702. *-----------------------------------------------------------------------
  703. *-- Programmer..: Miriam Liskin
  704. *-- Date........: 02/01/1993
  705. *-- Notes.......: Asks a yes/no/cancel question in a dialog window/box
  706. *-- Written for.: dBASE IV, 1.1
  707. *-- Rev. History: 04/19/1991 - Modified by Ken Mayer to become a 
  708. *--                            function
  709. *--               04/29/1991 - Modified to Ken Mayer add shadow
  710. *--               05/13/1991 - Modified to Ken Mayer remove need for 
  711. *--                            extra procedures (YES/NO) that were used
  712. *--                            for returning values from Menu
  713. *--                            (suggested by Clinton L. Warren (VBCES))
  714. *--               01/20/1992 - Modified by Martin Leon (HMan) to handle 
  715. *--                            user pressing 'Y' or 'N' keys (with ON 
  716. *--                            KEY ...).
  717. *--               06/11/1992 - Modified by Joey Carroll (JOEY) to allow
  718. *--                            answer choices to be "Yes", "No", or 
  719. *--                            "Cancel" or to allow for parameters to 
  720. *--                            pass the contents of the prompts. If none
  721. *--                            are passed, they default to "Yes", "No",
  722. *--                            "Cancel". Further modified to allow 
  723. *--                            specification of location by row if
  724. *--                            desired. Window size now varies as 
  725. *--                            parameters dictate.
  726. *--               09/21/1992 - Modified by JOEY to fix bug caused if 
  727. *--                            leading blanks in parameters cPrompt1,
  728. *--                            cPrompt2,cPrompt3.  Corrected example - 
  729. *--                            case pad()="PPAD1" instead of case 
  730. *--                            pad()=PPAD1
  731. *--               02/01/1993 - Mods by Lee Hite: Routine would not wait 
  732. *--                            for user response if "default" answer 
  733. *--                            did not match one of the prompts. Now 
  734. *--                            first prompt becomes default if no match
  735. *--                            is found on invocation. Also, match is no
  736. *--                            longer case sensitive.  Also made window 
  737. *--                            height variable if message lines 2 and/or 
  738. *--                            3 are null strings.  Finally, added 
  739. *--                            "confirmation" parameter which when set
  740. *--                            true will force user to press [Enter] 
  741. *--                            before function returns.
  742. *-- Calls.......: SHADOW           Procedure in PROC.PRG
  743. *--               CENTER           Procedure in PROC.PRG
  744. *--               ISBLANK()        Function in MISC.PRG, Internal in 1.5
  745. *-- Called by...: Any
  746. *-- Usage.......: YesNoCan("<cAnswer>","<cMess1>","<cMess2>",;
  747. *--                        "<cMess3>","<cPrompt1>","<cPrompt2>",;
  748. *--                        "<cPrompt3>",<nTopRow>,"<cColor>",[lConfirm])
  749. *-- Example.....: cAnswer="Y"
  750. *--               cAnswer=YesNoCan(cAnswer,"*** Warning ***",;
  751. *--                            "A serious error has occured.",;
  752. *--                             "Choose carefully.","Proceed",;
  753. *--                             "Retry","Cancel",10,;
  754. *--                             "w+/r,n/w,w+/r")
  755. *--               do case
  756. *--                  case cAnswer="Y"    && OR case pad()="PPAD1"
  757. *--                     * do your thing
  758. *--                  case cAnswer="N"    && OR case pad()="PPAD2"
  759. *--                     skip
  760. *--                  case cAnswer="C"    && OR case pad()="PPAD3"
  761. *--                     * e.g. - return
  762. *--               endcase
  763. *--
  764. *--                 The middle set of colors should be different, as 
  765. *--                 they will be the colors of the YES/NO selections ...
  766. *--                 Options may be blank by using nul values ("")
  767. *-- Returns.....: First character of selected pad
  768. *-- Parameters..: cAnswer  =  default value (Yes or No or Cancel) for 
  769. *--                           menu
  770. *--               cMess1   =  First line of Message
  771. *--               cMess2   =  Second line of message
  772. *--               cMess3   =  Third line of message
  773. *--               cPrompt1 =  Optional prompt for left pad
  774. *--               cPrompt2 =  Optional prompt for middle pad
  775. *--               cPrompt3 =  Optional prompt for right pad
  776. *--               nTopRow  =  Optional top row of window
  777. *--               cColor   =  Optional colors for window/menu/box
  778. *--               lConfirm =  Optional "confirmation" parameter -- if 
  779. *--                           true user must press [Enter], otherwise 
  780. *--                           pressing a valid prompt key automatically 
  781. *--                           returns
  782. *-----------------------------------------------------------------------
  783.  
  784.    parameter cAnswer,cMess1,cMess2,cMess3,;
  785.       cPrompt1,cPrompt2,cPrompt3,nTopRow,cColor,lConfirm
  786.    private nLMargin,nRMargin,lWrap,nTopRowMax,cKey1,cKey2,cKey3,;
  787.       nWinWidth,cConfirm, nWinHgth, nMsgRow
  788.    private cPrompt1,cPrompt2,cPrompt3 
  789.    
  790.    *-- save screen so we can restore ...
  791.    save screen to sYesNoCan
  792.    * locate top row of window
  793.    m->nTopRowMax = iif(set("STATUS") = "OFF",17,14) 
  794.                                                 && protect Status Line
  795.    m->nTopRow = iif(isblank(m->nTopRow),14,m->nTopRow) 
  796.                                                 && no parameter passed
  797.    m->nTopRow = min(m->nTopRowMax,m->nTopRow)
  798.  
  799.    * set pad prompts if none passed
  800.    m->cPrompt1 = iif(isblank(m->cPrompt1),"Yes",m->cPrompt1)
  801.    m->cPrompt2 = iif(isblank(m->cPrompt2),"No",m->cPrompt2)
  802.    m->cPrompt3 = iif(isblank(m->cPrompt3),"Cancel",m->cPrompt3)
  803.    m->cAnswer = iif(isblank(m->cAnswer),m->cPrompt1,m->cAnswer)
  804.  
  805.    * program bombs if prompts passed contain leading blanks
  806.    m->cPrompt1 = ltrim(trim(m->cPrompt1))
  807.    m->cPrompt2 = ltrim(trim(m->cPrompt2))
  808.    m->cPrompt3 = ltrim(trim(m->cPrompt3))
  809.  
  810.    * determine how wide the window needs to be
  811.    m->nWinWidth = max(19,len(m->cPrompt1 + m->cPrompt2 + m->cPrompt3);
  812.                                                                   +13)
  813.    m->nWinWidth = max(m->nWinWidth,len(cMess1)+4)
  814.    m->nWinWidth = max(m->nWinWidth,len(cMess2)+4)
  815.    m->nWinWidth = max(m->nWinWidth,len(cMess3)+4)
  816.    * and how high it needs to be
  817.    m->nWinHgth = iif(""=m->cMess2,7,8)
  818.    m->nWinHgth = iif(""=m->cMess3,m->nWinHgth-1,m->nWinHgth)
  819.    * and center it
  820.    define window wYesNoCan from m->nTopRow,40-(m->nWinWidth+2)/2 ;
  821.       to m->nTopRow+m->nWinHgth-1,40+(m->nWinWidth+2)/2 ;
  822.       double color &cColor.
  823.    define menu mYesNoCan
  824.    define pad pPad1 of mYesNoCan Prompt "["+m->cPrompt1+"]" ;
  825.       at m->nWinHgth-3,02
  826.    * center middle prompt between other two, not center of window
  827.    define pad pPad2 of mYesNoCan Prompt "["+m->cPrompt2+"]" at ;
  828.       m->nWinHgth-3, ((m->nWinWidth-len(m->cPrompt2))/2+;
  829.       (len(m->cPrompt1)-len(m->cPrompt3))/2)
  830.    define pad pPad3 of mYesNoCan Prompt "["+m->cPrompt3+"]"  ;
  831.       at m->nWinHgth-3,(m->nWinWidth-3)-(len(m->cPrompt3))
  832.    on selection pad pPad1 of mYesNoCan deactivate menu
  833.    on selection pad pPad2 of mYesNoCan deactivate menu
  834.    on selection pad pPad3 of mYesNoCan deactivate menu
  835.    
  836.    activate screen
  837.    do shadow with m->nTopRow,40-(m->nWinWidth+2)/2,m->nTopRow+;
  838.                   m->nWinHgth-1,40+(m->nWinWidth+2)/2
  839.    activate window wYesNoCan
  840.    
  841.    do center with 0,m->nWinWidth,"",cMess1       && center the text
  842.    *-- deal with blank message lines
  843.    m->nMsgRow = 2
  844.    if "" <> m->cMess2
  845.       do center with m->nMsgRow,m->nWinWidth,"",m->cMess2
  846.       m->nMsgRow = m->nMsgRow + 1
  847.    endif
  848.    if "" <> m->cMess3
  849.       do center with m->nMsgRow,m->nWinWidth,"",m->cMess3
  850.    endif
  851.    *-- deal with user pressing first key of prompt
  852.    m->cKey1 = left(m->cPrompt1,1)
  853.    m->cKey2 = left(m->cPrompt2,1)
  854.    m->cKey3 = left(m->cPrompt3,1)
  855.  
  856.    *-- set [CR] at end of keyboard command depending on "confirm" 
  857.    *-- parameter
  858.    m->cConfirm = iif(m->lConfirm,"",chr(13))
  859.  
  860.    on key label &cKey1. keyboard iif( PAD() = "PPAD1", "", ;
  861.       iif(pad() = "PPAD2", chr(19),CHR(4) )) + m->cConfirm
  862.    on key label &cKey2. keyboard iif( PAD() = "PPAD2",  "", ;
  863.       iif(pad() = "PPAD1",CHR(4),chr(19) )) + m->cConfirm
  864.    on key label &cKey3. keyboard iif( PAD() = "PPAD3", "", ;
  865.       iif(pad() = "PPAD2", CHR(4),chr(19))) + m->cConfirm
  866.    clear typeahead
  867.    *-- otherwise deal with regular "menu" abilities
  868.    do case
  869.       case upper(m->cAnswer)=upper(m->cKey1)
  870.            activate menu mYesNoCan pad pPad1
  871.       case upper(m->cAnswer)=upper(m->cKey2)
  872.            activate menu mYesNoCan pad pPad2
  873.       case upper(m->cAnswer)=upper(m->cKey3)
  874.            activate menu mYesNoCan pad pPad3
  875.       otherwise
  876.            activate menu mYesNoCan pad pPad1
  877.    endcase
  878.    
  879.    *-- clear out ON KEY settings ...
  880.    on key label &cKey1.
  881.    on key label &cKey2.
  882.    on key label &cKey3.
  883.    *-- reset environment
  884.    release window wYesNoCan
  885.    restore screen from sYesNoCan
  886.    release screen sYesNoCan
  887.    release menu mYesNoCan
  888.  
  889. RETURN upper(substr(prompt(),2,1))
  890. *-- EoF: YesNoCan()
  891.  
  892. PROCEDURE ProgBar2
  893. *-----------------------------------------------------------------------
  894. *-- Programmer..: Joey D. Carroll (JOEY)
  895. *-- Date........: 10/26/1992
  896. *-- Notes.......: A crippled version of PROGBAR for those who want it 
  897. *--               simple. A visual indicator of program activity, i.e. 
  898. *--               shows user program didn't die during long processes 
  899. *--               which do not normally show 'on screen'.  Serves same 
  900. *--               purpose as MONITOR, but is more graphic.
  901. *--               For best appearance, set cursor 'off' from calling
  902. *--               program, outside of the loop which calls PROGBAR.
  903. *-- Written for.: dBASE IV, 1.5
  904. *-- Rev. History: 06/28/1992 -- Original
  905. *--               10/26/1992 -- protected existing active window.
  906. *-- Calls.......: None
  907. *-- Called by...: Any
  908. *-- Usage.......: do PROGBAR2 with <nQuan>,<cWindCol>,<cFillCol1>,;
  909. *--                                <cFillCol2>
  910. *-- Example.....: *-- determine what process will be monitored and what 
  911. *--               *-- the final value will be, e.g. nReccount = 
  912. *--               *-- reccount()
  913. *--               use <anyfile>
  914. *--               nReccount = reccount()
  915. *--               set cursor off
  916. *--               scan
  917. *--                  do progbar2 with nReccount,",,w+/n","w+/r","w+/g"
  918. *--                  *-- do some needed process here
  919. *--               endscan
  920. *--               *-- cleanup
  921. *-- Returns.....: None
  922. *-- Parameters..: nQuan     = maximum number of iterations
  923. *--               cWindCol  = the window colors
  924. *--               cFillCol1 = color of ruler before process
  925. *--               cFillCol2 = color of ruler after process
  926. *-----------------------------------------------------------------------
  927.  
  928.    parameters nQuan,cWindCol,cFillCol1,cFillCol2   
  929.    private nWindWidth
  930.    m->nWindWidth = 78  && hard coded, wall to wall
  931.  
  932.    *-- skip this section if we've been here before
  933.    *-- this procedure called from inside a loop
  934.    *-- following section ignored except on first iteration thru loop
  935.    if type("nTimes") = "U"
  936.       save screen to sProgBar
  937.       public m->nFactor,m->nTimes,wPrevWind
  938.       wPrevWind = window()
  939.       if set("status") = "ON"  && different location if status "on"
  940.          define window wProgBar from 19,0 to 21,79 double ;
  941.                                        color &cWindCol.
  942.       else
  943.          define window wProgBar from 21,0 to 23,79 double ;
  944.                                        color &cWindCol.
  945.       endif   && set("status") = "ON"
  946.       activate window wProgBar
  947.       @ 0,0 say replicate(".",m->nWindWidth - 1)  && the ruler
  948.       @ 0,0 say "0%"                        && and some gradation %'s
  949.       @ 0,m->nWindWidth / 4 - 2 say "25%"
  950.       @ 0,m->nWindWidth / 2 - 2 say "50%"
  951.       @ 0,3*(m->nWindWidth / 4) - 2 say "75%"
  952.       @ 0,m->nWindWidth - 4 say "100%"
  953.       @ 0,0 fill to 0,m->nWindWidth - 1 color &cFillCol1.
  954.                                        && color of ruler before process
  955.       m->nFactor = m->nQuan/m->nWindWidth   
  956.                             && e.g. how many records per bar part(cols)
  957.       m->nTimes = 0  && times thru loop
  958.    endif      && type("nTimes") = "U"
  959.  
  960.    *-- the section will be processed as many times as required by nQuan
  961.    m->nTimes = m->nTimes+1
  962.    @ 0,0 fill to 0,int(m->nTimes/m->nFactor) ;
  963.          - iif(int(m->nTimes/m->nFactor) -1 >= 0,1,0) ;
  964.          color &cFillCol2.  && color of ruler as processing takes place
  965.  
  966.    if m->nTimes = m->nQuan  && we done
  967.       m->x = inkey(.5)      && leave on screen just a liitle while 
  968.                             && after completion
  969.       * cleanup your mess
  970.       release window wProgBar
  971.       restore screen from sProgBar
  972.       release screen sProgBar
  973.       *-- if window was active, re-activate
  974.       if .not. isblank(wPrevWind)
  975.          activate window &wPrevWind.
  976.       endif
  977.       release nProgBar,m->nFactor,m->nTimes,m->nWindWidth,m->x,wPrevWind
  978.    endif
  979.  
  980. RETURN
  981. *-- EoP: PROGBAR2
  982.  
  983. PROCEDURE MovePad
  984. *-----------------------------------------------------------------------
  985. *-- Programmer..: Angus Scott-Fleming (CIS: 75500,3223)
  986. *-- Date........: 07/29/1992
  987. *-- Notes.......: Used to move the selected pad in a dBASE Bar Menu if 
  988. *--               the user selects the first letter/key of the pad. The
  989. *--               routine doesn't re-evalute PAD(), and is based on 
  990. *--               Genifer code (improved on by Angus). This should be 
  991. *--               used with the ON KEY command.
  992. *--               NOTE: This routine assumes you are using the 
  993. *--               dUFLP/dHUNG standard for naming pads, and that the 
  994. *--               first character of each pad NAME is 'p' (i.e., pColor,
  995. *--               pExit, etc.).
  996. *-- Written for.: dBASE IV, 1.5, should work in 1.1.
  997. *-- Rev. History: 07/24/1992 -- Original
  998. *--               07/29/1992 -- Added header/notes.
  999. *-- Calls.......: None
  1000. *-- Called by...: Any
  1001. *-- Usage.......: do MovePad with <cLetter>,<lSelect>,<cChoices>
  1002. *-- Example.....: on key label "C" do MovePad with "C",.t.,cChoices
  1003. *-- Returns.....: None
  1004. *-- Parameters..: cLetter  = first letter/key on pad
  1005. *--               lSelect  = select pad, or move cursor to it? (Act as 
  1006. *--                          if user pressed <Enter> after moving 
  1007. *--                          to it)
  1008. *--               cChoices = list of possible choices (i.e., 
  1009. *--                                 "Enter,Edit,Delete,Print,Exit")
  1010. *-----------------------------------------------------------------------
  1011.  
  1012.    parameters cLetter, lSelect, cChoices
  1013.    private nToMove
  1014.  
  1015.    *-- determine how many pads to move, based on position of choice in 
  1016.    *-- list of choices (m->cChoices).
  1017.    m->nToMove = at(m->cLetter,m->cChoices) - ;
  1018.                 at(substr(pad(),2,1),m->cChoices)
  1019.  
  1020.    *-- if it is a negative value, move to the left, and press <Enter> if
  1021.    *-- lSelect = .t. (otherwise, just move there and stop).
  1022.    if m->nToMove < 0
  1023.       keyboard replicate(chr(5), -m->nToMove) + ;
  1024.                          iif(m->lSelect,chr(13),"")
  1025.    else
  1026.       keyboard replicate(chr(24), m->nToMove) + ;
  1027.                          iif(m->lSelect,chr(13),"")
  1028.    endif
  1029.  
  1030. RETURN
  1031. *-- EoP: MovePad
  1032.  
  1033. PROCEDURE Monitor
  1034. *-----------------------------------------------------------------------
  1035. *-- Programmer..: Miriam Liskin
  1036. *-- Date........: 06/08/1992
  1037. *-- Notes.......: Displays a status message to monitor a long-running 
  1038. *--                 operation that operates on multiple records . . . 
  1039. *--                 Should be used with MONITOROFF (below) to cleanup.
  1040. *-- Written for.: dBASE IV, 1.1
  1041. *-- Rev. History: 04/29/1991 - Modified by Ken Mayer to add shadow
  1042. *--               06/08/1992 - Modified to handle explicit color setting
  1043. *-- Calls.......: SHADOW               Procedure in PROC.PRG
  1044. *--               CENTER               Procedure in PROC.PRG
  1045. *-- Called by...: Any
  1046. *-- Usage.......: do monitor with "<cText>","<cColor>"
  1047. *-- Example.....: do monitor with "Processing REPORT.DBF",;
  1048. *--                                "rg+/gb,rg+/gb,rg+/gb"
  1049. *--               nRec = 0
  1050. *--               do while  && (or SCAN)
  1051. *--                  && stuff -- process records
  1052. *--                  nRec = nRec + 1
  1053. *--                  @4,30 display ltrim(str(nRec)) && current record
  1054. *--                                                 && in window MONITOR
  1055. *--               enddo  && (or endscan)
  1056. *--               do MonitorOff  && procedure to clean-up after this one
  1057. *-- Returns.....: None
  1058. *-- Parameters..: cText  = Text to display
  1059. *--               cColor = Colors for window
  1060. *-----------------------------------------------------------------------
  1061.  
  1062.    parameters cText,cColor
  1063.    private cTempCol
  1064.    
  1065.    save screen to sMonitor
  1066.    activate screen
  1067.    define window wMonitor From 10,10 to 18,70 double color &cColor.
  1068.    do shadow with 10,10,18,70
  1069.    activate window wMonitor
  1070.    
  1071.    do center with 1,60,"",m->cText
  1072.    do center with 2,60,"","Please do not interrupt"
  1073.    @4,10 say "Working on record          of " + ltrim(str(reccount(),5))
  1074.    
  1075. RETURN
  1076. *-- EoP: Monitor
  1077.  
  1078. PROCEDURE MonitorOff
  1079. *-----------------------------------------------------------------------
  1080. *-- Programmer..: Ken Mayer (CIS: 71333,1030)
  1081. *-- Date........: 05/23/1991
  1082. *-- Notes.......: Used to deal with ending routines for MONITOR
  1083. *--                 procedure above.
  1084. *-- Written for.: dBASE IV, 1.1
  1085. *-- Rev. History: 05/23/1991 -- Original
  1086. *-- Calls.......: None
  1087. *-- Called by...: Routine using MONITOR  Procedure in PROC.PRG
  1088. *-- Usage.......: do monitoroff
  1089. *-- Example.....: do monitoroff
  1090. *-- Returns.....: None
  1091. *-- Parameters..: None
  1092. *-----------------------------------------------------------------------
  1093.  
  1094.    release window wMonitor
  1095.    restore screen from sMonitor
  1096.    release screen sMonitor
  1097.    
  1098. RETURN
  1099. *-- EoP: MonitorOff
  1100.  
  1101. FUNCTION NewBorder
  1102. *-----------------------------------------------------------------------
  1103. *-- Programmer..: Kenneth J. Mayer (CIS: 71333,1030)
  1104. *-- Date........: 01/20/1993
  1105. *-- Notes.......: Will save current border setting (the returned value),
  1106. *--               and set a new one with one of a set of pre-defined
  1107. *--               borders. This will create a new variable if it doesn't
  1108. *--               already exist, called: c_Border, which is a PUBLIC 
  1109. *--               Character variable. The purpose is so that you can 
  1110. *--               keep using this string for other purpose (i.e., 
  1111. *--               DEFINE WINDOW and such ...)
  1112. *-- Written for.: dBASE IV, 1.5
  1113. *-- Rev. History: 01/20/1993 -- Original
  1114. *-- Calls.......: None
  1115. *-- Called by...: Any
  1116. *-- Usage.......: NewBorder("<cStyle>")
  1117. *-- Example.....: cOldBorder = NewBorder("K")
  1118. *--               @5,10 to 15,60  && draw box with new "border" setting
  1119. *--               *-- define a window with new "border" setting
  1120. *--               define window wTest from 10,20 to 20,60 &c_Border
  1121. *--               set border to &cOldBorder  && reset border to original
  1122. *-- Returns.....: Current border setting (before calling routine)
  1123. *-- Parameters..: cStyle = Style from one of the following:
  1124. *--                        A = Double
  1125. *--                                     …ÕÕÕÕª
  1126. *--                                     ∫    ∫
  1127. *--                                     »ÕÕÕÕº
  1128. *--                        B = Single
  1129. *--                                     ⁄ƒƒƒƒø
  1130. *--                                     ≥    ≥
  1131. *--                                     ¿ƒƒƒƒŸ
  1132. *--                        C = Panel
  1133. *--                                     €€€€€€
  1134. *--                                     €    €
  1135. *--                                     €€€€€€
  1136. *--                        D = None
  1137. *--                        E = Double Top, Single Left, Right, and 
  1138. *--                            Bottom
  1139. *--                                      ’ÕÕÕÕ∏
  1140. *--                                      ≥    ≥
  1141. *--                                      ¿ƒƒƒƒŸ
  1142. *--                        F = Single Top, Double Left, Right and Bottom
  1143. *--                                      ÷ƒƒƒƒ∑
  1144. *--                                      ∫    ∫
  1145. *--                                      »ÕÕÕÕº
  1146. *--                        G = Double Top, Left, Right, Single Bottom
  1147. *--                                      …ÕÕÕÕª
  1148. *--                                      ∫    ∫
  1149. *--                                      ”ƒƒƒƒΩ
  1150. *--                        H = Single Top, Left, Right, Double Bottom
  1151. *--                                      ⁄ƒƒƒƒø
  1152. *--                                      ≥    ≥
  1153. *--                                      ‘ÕÕÕÕæ
  1154. *--                        I = Double Top, Single Left and Right, 
  1155. *--                            Double Bottom
  1156. *--                                      ’ÕÕÕÕ∏
  1157. *--                                      ≥    ≥
  1158. *--                                      ‘ÕÕÕÕæ
  1159. *--                        J = Single Top, Double Left and Right, 
  1160. *--                            Single Bottom
  1161. *--                                      ÷ƒƒƒƒ∑
  1162. *--                                      ∫    ∫
  1163. *--                                      ”ƒƒƒƒΩ
  1164. *--                        K = Single Top and Left, Double Right and 
  1165. *--                            Bottom
  1166. *--                                      ⁄ƒƒƒƒ∑
  1167. *--                                      ≥    ∫
  1168. *--                                      ‘ÕÕÕÕº
  1169. *--                        L = Single Top, Double Left, Single Right, 
  1170. *--                            Double Bottom
  1171. *--                                      ÷ƒƒƒƒø
  1172. *--                                      ∫    ≥
  1173. *--                                      »ÕÕÕÕæ
  1174. *--                        M = Double Top and Left, Single Right and
  1175. *--                            Bottom
  1176. *--                                      …ÕÕÕÕ∏
  1177. *--                                      ∫    ≥
  1178. *--                                      ”ƒƒƒƒŸ
  1179. *--                        N = Double Top, Single Left, Double Right, 
  1180. *--                            Single Bottom
  1181. *--                                      ’ÕÕÕÕª
  1182. *--                                      ≥    ∫
  1183. *--                                      ¿ƒƒƒƒΩ
  1184. *--                        O = Double Top, Single Left, Double Right
  1185. *--                            and Bottom
  1186. *--                                      ’ÕÕÕÕª
  1187. *--                                      ≥    ∫
  1188. *--                                      ‘ÕÕÕÕº
  1189. *--                        P = Double Top, Left, Single Right, 
  1190. *--                            Double Bottom
  1191. *--                                      …ÕÕÕÕÕ∏
  1192. *--                                      ∫     ≥
  1193. *--                                      »ÕÕÕÕÕæ
  1194. *--                        Q = Single Top, Double Left, Single Right 
  1195. *--                            and Bottom
  1196. *--                                      ÷ƒƒƒƒƒø
  1197. *--                                      ∫     ≥
  1198. *--                                      ”ƒƒƒƒƒŸ
  1199. *--                        R = Single Top and Left, Double Right, 
  1200. *--                            Single Bottom
  1201. *--                                      ⁄ƒƒƒƒƒ∑
  1202. *--                                      ≥     ∫
  1203. *--                                      ¿ƒƒƒƒƒΩ
  1204. *--                        S = Panel, but with more room on the 
  1205. *--                            interior ... the default 'panel' mode 
  1206. *--                            for borders uses uses 220-223 ...
  1207. *--                                      fiflflflflfl›
  1208. *--                                      fi     ›
  1209. *--                                      fi‹‹‹‹‹›
  1210. *-----------------------------------------------------------------------
  1211.  
  1212.    parameters cStyle
  1213.    m->cReturn = set("BORDER") && current border -- if version of dBASE 
  1214.                               && is less than 1.5, comment this out ...
  1215.    
  1216.    if type("c_Border") = "U"  && if this is undefined
  1217.       public m->c_Border      &&   declare it as public
  1218.    endif
  1219.    
  1220.    *-- here we go ...
  1221.    do case
  1222.       case m->cStyle = "A"   
  1223.          m->c_Border = "DOUBLE"   && pre-defined
  1224.       case m->cStyle = "B"
  1225.          m->c_Border = "SINGLE"   && pre-defined
  1226.       case m->cStyle = "C"
  1227.          m->c_Border = "PANEL"    && pre-defined
  1228.       case m->cStyle = "D"
  1229.          m->c_Border = "NONE"     && pre-defined
  1230.       case m->cStyle = "E"
  1231.          *-- items are: top line, bottom line, left line, right line,
  1232.          *-- upper left corner, upper right corner, bottom left corner,
  1233.          *-- bottom right corner
  1234.          m->c_Border = "205,196,179,179,213,184,192,217"
  1235.       case m->cStyle = "F"
  1236.          m->c_Border = "196,205,186,186,214,183,200,188"
  1237.       case m->cStyle = "G"
  1238.          m->c_Border = "205,196,186,186,201,187,211,189"
  1239.       case m->cStyle = "H"
  1240.          m->c_Border = "196,205,179,179,218,191,212,190"
  1241.       case m->cStyle = "I"
  1242.          m->c_Border = "205,205,179,179,213,184,212,190"
  1243.       case m->cStyle = "J"
  1244.          m->c_Border = "196,196,186,186,214,183,211,189"
  1245.       case m->cStyle = "K"
  1246.          m->c_Border = "196,205,179,186,218,183,212,188"
  1247.       case m->cStyle = "L"
  1248.          m->c_Border = "196,205,186,179,214,191,200,190"
  1249.       case m->cStyle = "M"
  1250.          m->c_Border = "205,196,186,179,201,184,211,217"
  1251.       case m->cStyle = "N"
  1252.          m->c_Border = "205,196,179,186,213,187,192,189"
  1253.       case m->cStyle = "O"
  1254.          m->c_Border = "205,205,179,186,213,187,212,188"
  1255.       case m->cStyle = "P"
  1256.          m->c_Border = "205,205,186,179,201,184,200,190"
  1257.       case m->cStyle = "Q"
  1258.          m->c_Border = "196,196,186,179,214,191,211,217"
  1259.       case m->cStyle = "R"
  1260.          m->c_Border = "196,196,179,186,218,183,192,189"
  1261.       case m->cStyle = "S"
  1262.          m->c_Border = "223,220,222,221,222,221,222,221"
  1263.    endcase
  1264.    
  1265.    set border to &c_Border.
  1266.  
  1267. RETURN m->cReturn
  1268. *-- EoF: NewBorder
  1269.  
  1270. FUNCTION VidRow
  1271. *-----------------------------------------------------------------------
  1272. *-- Programmer..: Ken Mayer (CIS: 71333,1030)
  1273. *-- Date........: 01/28/1993
  1274. *-- Notes.......: Calls VDCURSOR.BIN (David Frankenbach, 
  1275. *--               CIS: 72147,2635) to return the ABSOLUTE position of 
  1276. *--               the current ROW on the screen, despite any active 
  1277. *--               windows, etc. This is based on original routines by 
  1278. *--               David Frankenbach, but includes the load/release in 
  1279. *--               one routine, rather than requiring three functions 
  1280. *--               to perform this ...
  1281. *--               ***************************
  1282. *--               ** REQUIRES VDCURSOR.BIN **
  1283. *--               ***************************
  1284. *-- Written for.: dBASE IV, 1.5
  1285. *-- Rev. History: 01/28/1993 -- Original
  1286. *-- Calls.......: VDCURSOR.BIN
  1287. *-- Called by...: Any 
  1288. *-- Usage.......: VidRow()
  1289. *-- Example.....: ?VidRow()
  1290. *-- Returns.....: Numeric ROW position for current row on screen
  1291. *-- Parameters..: None
  1292. *-----------------------------------------------------------------------
  1293.  
  1294.    private cX
  1295.    
  1296.    m->cX = space(2)          && define argument memvar
  1297.    load vdcursor             && load the .BIN file
  1298.    call vdcursor with m->cX  && call it with the memvar
  1299.    release module vdcursor   && release from memory
  1300.  
  1301. RETURN (asc(substr(m->cX,2))-1) 
  1302. *--               && return the value of the absolute cursor position
  1303. *-- EoF: VidRow()
  1304.  
  1305. FUNCTION VidCol
  1306. *-----------------------------------------------------------------------
  1307. *-- Programmer..: Ken Mayer (CIS: 71333,1030)
  1308. *-- Date........: 01/28/1993
  1309. *-- Notes.......: Calls VDCURSOR.BIN (David Frankenbach, 
  1310. *--               CIS: 72147,2635) to return the ABSOLUTE position of 
  1311. *--               the current COLUMN on the screen, despite any active 
  1312. *--               windows, etc. This is based on original routines by
  1313. *--               David Frankenbach, but includes the load/release in 
  1314. *--               one routine, rather than requiring three functions to
  1315. *--               perform this ...
  1316. *--               ***************************
  1317. *--               ** REQUIRES VDCURSOR.BIN **
  1318. *--               ***************************
  1319. *-- Written for.: dBASE IV, 1.5
  1320. *-- Rev. History: 01/28/1993 -- Original
  1321. *-- Calls.......: VDCURSOR.BIN
  1322. *-- Called by...: Any 
  1323. *-- Usage.......: VidCol()
  1324. *-- Example.....: ?VidCol()
  1325. *-- Returns.....: Numeric COLUMN position for current Col on screen
  1326. *-- Parameters..: None
  1327. *-----------------------------------------------------------------------
  1328.  
  1329.    private cX
  1330.    
  1331.    m->cX = space(2)          && define argument memvar
  1332.    load vdcursor             && load the .BIN file
  1333.    call vdcursor with m->cX  && call it with the memvar
  1334.    release module vdcursor   && release from memory
  1335.  
  1336. RETURN (asc(substr(m->cX,1))-1) 
  1337. *--                && return the value of the absolute cursor position
  1338. *-- EoF: VidCol()
  1339.  
  1340. FUNCTION PwdMask
  1341. *-----------------------------------------------------------------------
  1342. *-- Programmer..: Kenneth J. Mayer (CIS: 71333,1030)
  1343. *-- Date........: 01/29/1993
  1344. *-- Notes.......: Designed to display a mask on the screen when a user 
  1345. *--               is entering a password, rather than a blank surface. 
  1346. *--               Should handle backspaces to delete ... ASSUMES 
  1347. *--               <cField> is a memvar.
  1348. *--               ***************************
  1349. *--               ** REQUIRES VDCURSOR.BIN **
  1350. *--               ***************************
  1351. *-- Written for.: dBASE IV, 1.5
  1352. *-- Rev. History: 01/29/1993 -- Original
  1353. *-- Calls.......: VidRow()             Function in SCREEN.PRG
  1354. *--               VidCol()             Function in SCREEN.PRG
  1355. *-- Called by...: Any
  1356. *-- Usage.......: PwdMask("<cField>"[,<nMaskChar>])
  1357. *-- Example.....: @5,10 get password when PwdMask("Password");
  1358. *--                      valid required .not. isblank(password);
  1359. *--                      error chr(7)+"Password cannot be blank)
  1360. *-- Returns.....: .T., and field will have password placed in it when 
  1361. *--               done.
  1362. *-- Parameters..: cField    = name of the field
  1363. *--               nMaskChar = ASCII code for mask character. 
  1364. *--                           OPTIONAL parameter.
  1365. *--                           If not provided, will use asterisk. 
  1366. *--                           Suggested characters include: 
  1367. *--                           176,177,178,219,248,249,254
  1368. *--                            ∞   ±   ≤   €   ¯   ˘   ˛
  1369. *-----------------------------------------------------------------------
  1370.  
  1371.    parameters cField, nMaskChar
  1372.    private nLength, nChar, nX
  1373.    
  1374.    *-- deal with mask character
  1375.    if type("NMASKCHAR") = "L"
  1376.       m->nMaskChar = 42               && *
  1377.    endif
  1378.    
  1379.    m->lCursor = set("CURSOR") = "ON"
  1380.    set cursor off          && rather than have the cursor in the way ...
  1381.    m->nLength = len(&cField.)   && get length of current field
  1382.    m->nChar = 0                 && input character
  1383.    m->nRow = vidrow()           && get absolute cursor location
  1384.    m->nCol = vidcol()           && ditto
  1385.    m->cTemp = ""                && initialize temp memvar
  1386.    do while len(m->cTemp) < m->nLength .and. m->nChar # 13  
  1387.                                 && loop until we hit end of field
  1388.                                 && or user presses <Enter>
  1389.    
  1390.       m->nChar = inkey(0)       && wait for user to enter something
  1391.       
  1392.       do case  
  1393.                                     
  1394.          case m->nChar = 127         && <BackSpace>
  1395.             if isblank(m->cTemp)     && if empty, don't delete anything
  1396.                ?? chr(7)             && instead, BEEP
  1397.             else
  1398.                m->cTemp = left(m->cTemp,len(m->cTemp)-1)  && backup one
  1399.             endif
  1400.             
  1401.          case (m->nChar => 65 .and. m->nChar <= 90) .or.;
  1402.          (m->nChar => 97 .and. m->nChar <= 122) 
  1403.                                  && alphabetic input only
  1404.             m->cTemp = m->cTemp + chr(m->nChar)  && add character
  1405.             
  1406.          case m->nChar = 13           && <Enter>
  1407.             exit
  1408.             
  1409.          otherwise
  1410.             ?? chr(7)                 && otherwise, BEEP
  1411.             loop
  1412.       endcase
  1413.       
  1414.       *-- create the current "mask", padding with spaces ...
  1415.       m->cMask = replicate(chr(m->nMaskChar),len(m->cTemp)) +;
  1416.                  space(m->nLength-len(m->cTemp))
  1417.       *-- display it in same color as the current "GET"
  1418.       @m->nRow,m->nCol get m->cMask
  1419.       clear gets
  1420.       *-- put password into current memvar
  1421.       store m->cTemp to &cField.
  1422.       
  1423.    enddo
  1424.    
  1425.    *-- turn cursor on if it was prior to this routine
  1426.    if m->lCursor
  1427.       set cursor on
  1428.    endif
  1429.    
  1430.    keyboard chr(13)   && send a final <Enter> to exit this GET
  1431.    
  1432. RETURN .T.
  1433. *-- EoF: PwdMask()
  1434.  
  1435. PROCEDURE MultiPick
  1436. *-----------------------------------------------------------------------
  1437. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  1438. *-- Date........: 02/06/1993
  1439. *-- Notes.......: Permits selecting 0 or more elements of an array.
  1440. *--               The array must contain two columns, the first of which
  1441. *--               contains the prompt for the row and the second of 
  1442. *--               which contains logical .T. if the row is selected by 
  1443. *--               default, or .F.  Array may contain additional columns.
  1444. *--                     This is written for programmers, not end users.
  1445. *--               It assumes the active window and border style are set 
  1446. *--               before it is called, and no error handling is provided 
  1447. *--               for attempts to write outside the current window, 
  1448. *--               impossible colors, truncation of prompts or other 
  1449. *--               calling errors that should become evident on testing.
  1450. *--
  1451. *--               If array contains elements "Hydrangea",.T. and 
  1452. *--               "Tulip",.F., initial display after setting a window 
  1453. *--               and calling will be something like this:
  1454. *--
  1455. *--                  [ ˚ ] Hydrangea
  1456. *--                  [   ] Tulip
  1457. *--
  1458. *--               This program will use the mouse if two conditions 
  1459. *--               exist:
  1460. *--                   1) The variable nG_MusClic must exist and must 
  1461. *--               hold the inkey() value of the character "keyboarded" 
  1462. *--               for a click by the mouse-event handler.  Note that 
  1463. *--               this is often, but need not be, the same as 
  1464. *--               asc( <character> ).
  1465. *--                   2) The mouse must be made active and visible by a
  1466. *--               mouse-control .bin such as JPMOUSE.BIN and 
  1467. *--               MUSCLICK.BIN must be loaded and installed.
  1468. *--               *******************************
  1469. *--               **** REQUIRES MUSCLICK.BIN ****
  1470. *--               ****          JPMOUSE.BIN  ****
  1471. *--               ****          VDCURSOR.BIN ****
  1472. *--               *******************************
  1473. *-- Written for.: dBASE IV, 1.5
  1474. *-- Rev. History: 01/16/93 - original procedure
  1475. *--               02/06/93 - revised to use cWnSize, etc.
  1476. *--               02/24/93 - parameters changed, functions called moved 
  1477. *--                          out
  1478. *--               02/28/93 - symbolic constants and support for tab 
  1479. *--                          added
  1480. *-- Calls.......: SMultPick        Child procedure to paint screen
  1481. *--               Arrayrows()      Function in Array.prg
  1482. *--               MUSCLICK.BIN     Binary mouse-event handler
  1483. *--               CWnSize()        Function to find window size
  1484. *--               CWnDecode()      Function to decode the above
  1485. *--               YnMouse()        Yesno function for mouse
  1486. *--               NormColors()     Function to return normal colors
  1487. *--               HighColors()     Function to return highlight colors
  1488. *--               ForeColor()      Function to return foreground color
  1489. *-- Called by...: Any
  1490. *-- Usage.......: DO Multipick WITH <cArray>,<nDown>,<nLast>,<nRows>,;
  1491. *--                                 <nLength>,<cColors> [, <cCheck> ]]
  1492. *-- Example.....: DO Multipick WITH "Myarray",3,15,10,18,"RG+/G,N/W",;
  1493. *--                                 chr(2)
  1494. *-- Parameters..: cArray      = Name of the array of selectable items.
  1495. *--                             See Notes, above, for required 
  1496. *--                             structure.
  1497. *--               nDown       = first useable row of window
  1498. *--               nLast       = last useable row of window
  1499. *--               nRows       = number of items to show on screen at 
  1500. *--                             once
  1501. *--               nLength     = maximum length of prompts
  1502. *--               cColors     = optional, colors to use for noncurrent
  1503. *--                             and current items.  Default is NORMAL 
  1504. *--                             and HIGHLIGHT colors for the current 
  1505. *--                             window. Pass default as .F. if cCheck 
  1506. *--                             is included.
  1507. *--               cCheck      = optional, character to use to show 
  1508. *--                             selection. Default is "˚".  See "cBox" 
  1509. *--                             variables in the procedure for 
  1510. *--                             bracketing characters.
  1511. *-- Also uses...: global numeric variable nG_MusClic, giving the inkey()
  1512. *--               value of the character "keyboarded" by a mouse click.
  1513. *--               If this variable does not exist, mouse support is 
  1514. *--               absent.
  1515. *-- Side effects: On return, the values of the second column of the 
  1516. *--               array are .T. or .F. in accordance with selections 
  1517. *--               made.
  1518. *-- Special note: The CWnSize function called by this routine uses
  1519. *--               VDCURSOR.BIN, which must be available for this routine
  1520. *--               to work, and disables any ON ERROR trap.
  1521. *-----------------------------------------------------------------------
  1522.  
  1523.    parameters cArray, nDown, nLast, nRows, nLength, cColors, cCheck
  1524.    private cChar, cCols, cNorm, cHigh, nAt, nTop, nKey, cBoxl, ;
  1525.            cBoxr
  1526.    private nElems, lGotMouse, nMTop, nMBot, nMLeft, nMRight, cCols
  1527.    private cMrow, cMcol, nMrow, nMcol, cEsc, cWin, nWinTop, ;
  1528.            nWinLeft
  1529.    private nWinBot, nWinRight, nK, cK, cTemp, nX, cQuit, nRo, ;
  1530.            lOnPicks
  1531.    private lOk
  1532.  
  1533.    *  These "symbolic constants" are C-style, just to avoid "magic
  1534.    *  numbers" scattered throughout the routine.  Of course, they
  1535.    *  may also slow it down absent a true compiler
  1536.    private NBOXLEN, NEXTRAROWS, NPADLEN, NTWOPADS
  1537.    m->nBoxLen    =  6     && length of the "[ ˚ ] " structure
  1538.    m->nExtraRows =  4     && blank row at top, 3 rows for quit pads
  1539.    m->nPadLen    =  6     && length of the OK and Cancel pads
  1540.    m->nTwoPads   = 13     && length of two pads and a space between
  1541.  
  1542.    * set escape
  1543.    m->cEsc = set("ESCAPE")
  1544.    set escape off
  1545.  
  1546.    * set delimiter chars
  1547.    m->cBoxL = "[ "
  1548.    m->cBoxR = " ] "
  1549.  
  1550.    * set colors if specified
  1551.    if type( "cColors" ) = "C"
  1552.       m->cCols = m->cColors
  1553.    else
  1554.       m->cCols = set( "ATTRIBUTES" )
  1555.       m->cCols = left( m->cCols, at( "&", m->cCols ) - 2 )
  1556.    endif
  1557.    m->cNorm = NormColors( m->cCols )
  1558.    m->cHigh = HighColors( m->cCols )
  1559.    * set up quit pad colors
  1560.    m->cQuit = m->cHigh
  1561.  
  1562.    * set checkmark char, default is "˚" ( chr( 251 ) )
  1563.    m->cChar = iif( type( "cCheck" ) # "L", m->cCheck, "˚" )
  1564.  
  1565.    * calculate array rows and set up temporary array for restoration
  1566.    m->nElems = arrayrows( m->cArray )
  1567.    declare cTemp[ m->nElems ]
  1568.    m->nX = 1
  1569.    do while m->nX <= m->nElems
  1570.       cTemp[ m->nX ] = &cArray.[ m->nX, 2 ]
  1571.       m->nX = m->nX + 1
  1572.    enddo
  1573.  
  1574.    *  find borders of current window and determine centering offset
  1575.    m->cWin = cWnSize()
  1576.    if len( m->cWin ) > 0
  1577.       m->nWinTop   = cWnDecode( m->cWin, "T" )
  1578.       m->nWinLeft  = cWnDecode( m->cWin, "L" )
  1579.       m->nWinBot   = cWnDecode( m->cWin, "B" )
  1580.       m->nWinRight = cWnDecode( m->cWin, "R" )
  1581.    else
  1582.       activate screen
  1583.       ? "Can't find VDCURSOR.BIN - aborting"
  1584.       wait
  1585.       cancel
  1586.    endif
  1587.    m->nRight = int( ( m->nWinRight - m->nWinLeft - m->nBoxLen - ;
  1588.                       m->nLength ) / 2 )
  1589.    m->nCkCol = m->nRight + 2
  1590.  
  1591.    *  we need at least 13 columns for the quit pads, and enough for
  1592.    *  the checkbox table itself
  1593.    if m->nWinRight - m->nWinLeft < max( m->nTwoPads, m->nBoxLen + ;
  1594.                                                      m->nLength )
  1595.       activate screen
  1596.       ? "Too few columns in this window - aborting"
  1597.       wait
  1598.       cancel
  1599.    endif
  1600.  
  1601.    *  determine rows to use if window is small
  1602.    m->nRo = min( m->nRows, min( m->nLast - m->nDown, ;
  1603.                  m->nWinBot - m->nWinTop - m->nExtraRows ) )
  1604.    if m->nRo < 1
  1605.       activate screen
  1606.       ? "Too few rows in this window - aborting"
  1607.       wait
  1608.       cancel
  1609.    endif
  1610.  
  1611.    * test for mouse support and set boundaries of active click area
  1612.    * nMx variables represent absolute screen positions of the edges
  1613.    * of the checkbox table
  1614.    m->lGotMouse = .F.
  1615.    if type( "nG_MusClick" ) = "N"
  1616.       m->lGotMouse = .T.
  1617.       m->nMTop   = m->nWinTop +  m->nDown - 1     && row above table
  1618.       m->nMLeft  = m->nWinLeft + m->nRight        && left edge of table
  1619.       m->nMBot   = m->nMTop + m->nRo + 1          && row below table
  1620.       m->nMRight = m->nMLeft + m->nBoxLen + m->nLength - 1 && right edge
  1621.    endif
  1622.  
  1623.    * position quit pads ( they are displayed by Smultpick )
  1624.    * nLpad and nRpad are column offsets within the active window
  1625.    * of the two pads, "  OK  " and "Cancel"
  1626.    if m->nPadLen + m->nLength > m->nTwoPads
  1627.       m->nLPad = m->nRight
  1628.    else
  1629.       m->nLPad = int( ( m->nWinRight - m->nWinLeft ) / 4 ) -;
  1630.                       ( m->nPadLen / 2 )
  1631.    endif
  1632.    m->nRPad = m->nWinRight - m->nWinLeft - m->nPadLen - m->nLPad
  1633.  
  1634.    * initialize display as if "Home" had been pressed
  1635.    * nTop is the index into the array of the element to be shown
  1636.    *   on the top row of the table
  1637.    * nHigh is the index into the array of the element to be shown
  1638.    *   highlighted ( the current element )
  1639.    * lOnPicks is the "focus"; .T. means we are in the pick table,
  1640.    *   not on the quit pads
  1641.    m->nTop = 1
  1642.    m->nHigh = m->nTop
  1643.    keyboard "{Home}"
  1644.    m->lOnPicks = .T.
  1645.  
  1646.    * commence main key-handling loop
  1647.    do while .T.
  1648.       m->nKey = inkey()
  1649.       if m->nKey = 0
  1650.          loop
  1651.       endif
  1652.       do case
  1653.          case m->nKey = 23      && Ctrl-End
  1654.              exit
  1655.          case m->nKey = 27      && Escape
  1656.              if YesQuit()
  1657.                 exit
  1658.              endif
  1659.          case m->nKey = 79 .or. m->nKey = 111   && 'O' or 'o'
  1660.              exit
  1661.          case m->nKey = 67 .or. m->nKey = 99    && 'C' or 'c'
  1662.              if YesQuit()
  1663.                 exit
  1664.              endif
  1665.          case m->nKey = 9                    && Tab
  1666.              if m->lOnPicks
  1667.                 m->lOk = .T.                 && default tab is "OK"
  1668.                 @ row(), m->nRight say m->cBoxL + ;
  1669.                 iif( &cArray.[ m->nHigh, 2], ;
  1670.                          m->cChar, " " ) + m->cBoxR color &cNorm.
  1671.                 @ row(), col() say left( &cArray.[ m->nHigh, 1 ] ;
  1672.                      + space( m->nLength ), m->nLength ) color &cNorm.
  1673.                 @ m->nLast, m->nLPad + m->nPadLen / 2 say ""
  1674.              else
  1675.                 do SmultPick
  1676.              endif
  1677.              m->lOnPicks = .not. m->lOnPicks
  1678.          case m->lGotMouse .and. m->nKey = nG_MusClick   && mouse click
  1679.              store chr(255) to m->cMRow, m->cMCol
  1680.              call MUSCLICK with m->cMRow, m->cMCol
  1681.              m->nMRow = asc( m->cMRow )
  1682.              m->nMCol = asc( m->cMCol )
  1683.              if m->nMRow >= m->nMTop .and. m->nMRow <= m->nMBot .and. ;
  1684.                 m->nMCol >= m->nMLeft .and. m->nMCol <= m->nMRight   
  1685.                                            && in active area
  1686.                 m->nAt = m->nHigh - m->nTop + m->nMTop + 1
  1687.                 do case
  1688.                    case m->nMRow = m->nAt
  1689.                       keyboard chr( 13 )
  1690.                    case m->nMRow = m->nMTop
  1691.                       keyboard "{PgUp}"
  1692.                    case m->nMRow = m->nMBot
  1693.                       keyboard "{PgDn}"
  1694.                    case m->nMRow > m->nAt
  1695.                       do while m->nAt < m->nMRow
  1696.                          keyboard "{DNARROW}"
  1697.                          m->nAt = m->nAt + 1
  1698.                       enddo
  1699.                    case m->nMRow < m->nAt
  1700.                       do while m->nAt > m->nMRow
  1701.                          keyboard "{UPARROW}"
  1702.                          m->nAt = m->nAt - 1
  1703.                       enddo
  1704.                 endcase
  1705.               else
  1706.                  * if it was on a pad
  1707.                  if m->nMRow = m->nWinTop + m->nLast
  1708.                        if m->nMCol >= m->nWinLeft + m->nLPad .and.;
  1709.                        m->nMCol < m->nWinLeft + ;
  1710.                        m->nLPad + m->nPadLen
  1711.                     keyboard "O"
  1712.                     loop
  1713.                  endif
  1714.                  if m->nMCol >= m->nWinLeft + m->nRPad .and. ;
  1715.                        m->nMCol < m->nWinLeft + ;
  1716.                       m->nRPad + m->nPadLen
  1717.                     keyboard "C"
  1718.                     loop
  1719.                   endif
  1720.                endif
  1721.                keyboard "{Esc}"
  1722.             endif
  1723.          otherwise
  1724.              if m->lOnPicks
  1725.                 do case
  1726.                    case m->nKey = 26      && Home
  1727.                         m->nTop = 1
  1728.                         m->nHigh = m->nTop
  1729.                         do SMultPick
  1730.                    case m->nKey = 2       && End
  1731.                         m->nTop = m->nElems - m->nRo + 1
  1732.                         m->nHigh = m->nElems
  1733.                         do SMultPick
  1734.                    case m->nKey = 24        && down arrow
  1735.                       if m->nHigh = m->nTop + m->nRo - 1 .or.;
  1736.                           m->nHigh = m->nElems
  1737.                            keyboard "{PgDn}"
  1738.                         else
  1739.                            @ m->nHigh - m->nTop + m->nDown, ;
  1740.                                    m->nRight say ""
  1741.                            @ row(), m->nRight say m->cBoxL + ;
  1742.                                 iif( &cArray.[ m->nHigh, 2], ;
  1743.                                 m->cChar, " " ) + m->cBoxR ;
  1744.                                 color &cNorm.
  1745.                            @ row(), col() say ;
  1746.                                left( &cArray.[ m->nHigh, 1 ] ;
  1747.                                + space( m->nLength ), m->nLength );
  1748.                                color &cNorm.
  1749.                            m->nHigh = m->nHigh + 1
  1750.                            @ row() + 1, m->nRight say m->cBoxL + ;
  1751.                                iif( &cArray.[ m->nHigh, 2], ;
  1752.                                m->cChar, " " ) +m->cBoxR ;
  1753.                                color &cHigh.
  1754.                            @ row(), col() say ;
  1755.                                left( &cArray.[ m->nHigh, 1 ] ;
  1756.                                + space( m->nLength ), ;
  1757.                                m->nLength ) color &cHigh.
  1758.                            @ row(), m->nCkCol say ""
  1759.                        endif
  1760.                   case m->nKey = 5         && up arrow
  1761.                        if m->nHigh = m->nTop
  1762.                           keyboard "{PgUp}"
  1763.                        else
  1764.                           @ m->nHigh - m->nTop + m->nDown, ;
  1765.                               m->nRight say ""
  1766.                           @ row(), m->nRight say m->cBoxL + ;
  1767.                              iif( &cArray.[ m->nHigh, 2], ;
  1768.                              m->cChar, " " ) + m->cBoxR ;
  1769.                              color &cNorm.
  1770.                           @ row(), col() say ;
  1771.                              left( &cArray.[ m->nHigh, 1 ] ;
  1772.                              + space( m->nLength ),;
  1773.                              m->nLength ) color &cNorm.
  1774.                            m->nHigh = max( 1, m->nHigh - 1 )
  1775.                            @ row() - 1, m->nRight say m->cBoxL + ;
  1776.                                    iif( &cArray.[ m->nHigh, 2], ;
  1777.                                    m->cChar, " " ) + m->cBoxR ;
  1778.                                    color &cHigh.
  1779.                            @ row(), col() say ;
  1780.                                left( &cArray.[ m->nHigh, 1 ] ;
  1781.                                + space( m->nLength ), m->nLength ) ;
  1782.                                color &cHigh.
  1783.                            @ row(), m->nCkCol say ""
  1784.                        endif
  1785.                   case m->nKey = 32 .or. m->nKey = 13  
  1786.                                 && space and enter are toggles
  1787.                        &cArray.[ m->nHigh, 2 ] = ;
  1788.                              .not. &cArray[ m->nHigh, 2 ]
  1789.                        @ row(), m->nCkCol say ;
  1790.                            iif( &cArray.[ m->nHigh, 2], ;
  1791.                             m->cChar, " " ) ;
  1792.                                     color &cHigh.
  1793.                         @ row(), m->nCkCol say ""
  1794.                   case m->nKey = 3      && PgDn
  1795.                         if m->nHigh = m->nTop + m->nRo - 1 .or.;
  1796.                            m->nHigh = m->nElems
  1797.                            m->nTop = min( m->nHigh, m->nElems - ;
  1798.                              m->nRows + 1 )
  1799.                            do SmultPick
  1800.                         else
  1801.                            @ row(), m->nRight say m->cBoxL + ;
  1802.                                  iif( &cArray.[ m->nHigh, 2], ;
  1803.                                   m->cChar, " " ) + m->cBoxR ;
  1804.                                   color &cNorm.
  1805.                            @ row(), col() say ;
  1806.                              left( &cArray.[ m->nHigh, 1 ] ;
  1807.                              + space( m->nLength ), m->nLength ) ;
  1808.                              color &cNorm.
  1809.                            m->nHigh = m->nTop + m->nRo - 1
  1810.                            @ m->nDown + m->nRo - 1, m->nRight say ""
  1811.                            @ row(), m->nRight say m->cBoxL + ;
  1812.                               iif( &cArray.[ m->nHigh, 2], ;
  1813.                               m->cChar, " " ) + m->cBoxR color &cHigh.
  1814.                            @ row(), col() say ;
  1815.                               left( &cArray.[ m->nHigh, 1 ] ;
  1816.                               + space( m->nLength ), m->nLength );
  1817.                               color &cHigh.
  1818.                            @ row(), m->nCkCol say ""
  1819.                         endif
  1820.                     case m->nKey = 18      && PgUp
  1821.                         if m->nHigh = m->nTop
  1822.                            m->nTop = max( 1, m->nHigh - m->nRo + 1 )
  1823.                            do SmultPick
  1824.                         else
  1825.                            m->nHigh = m->nTop
  1826.                            @ m->nDown, m->nRight say ""
  1827.                            @ row(), m->nRight say m->cBoxL + ;
  1828.                            iif( &cArray.[ m->nHigh, 2], ;
  1829.                               m->cChar, " " ) + m->cBoxR color &cHigh.
  1830.                            @ row(), col() say;
  1831.                               left( &cArray.[ m->nHigh, 1 ] ;
  1832.                               + space( m->nLength ), m->nLength );
  1833.                            color &cHigh.
  1834.                            @ row(), m->nCkCol say ""
  1835.                        endif
  1836.                 endcase
  1837.               else
  1838.                 do case
  1839.                    case m->nKey = 32 .or. m->nKey = 4 .or. m->nKey = 19
  1840.                                               && space, r & l
  1841.                         m->lOk = .not. m->lOk
  1842.                       @ m->nLast, iif( m->lOk, m->nLPad, m->nRPad ) +;
  1843.                       m->nPadLen / 2 say ""
  1844.                    case m->nKey = 13        && and enter quits
  1845.                         if m->lOk
  1846.                            keyboard "{CTRL-END}"
  1847.                         else
  1848.                            keyboard "{ESC}"
  1849.                         endif
  1850.                 endcase
  1851.               endif
  1852.           endcase
  1853.         enddo
  1854.  
  1855.         if m->cEsc ="ON"
  1856.           set escape on
  1857.         endif
  1858. RETURN
  1859. *-- EoP: MultiPick
  1860.  
  1861. PROCEDURE SMultPick
  1862. *-----------------------------------------------------------------------
  1863. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  1864. *-- Date........: 01/16/1993
  1865. *-- Notes.......: Does screen display loop for Multipick procedure.
  1866. *-- Written for.: dBASE IV, 1.5
  1867. *-- Rev. History: Original function 01/16/1993.
  1868. *-- Calls.......: None
  1869. *-- Called by...: Multipick
  1870. *-- Usage.......: DO SMultpick
  1871. *-- Parameters..: None, but procedure uses various variables set by the
  1872. *--               parent Multipick procedure.
  1873. *-----------------------------------------------------------------------
  1874.  
  1875.    private nThisOff, nThisRow, nThisElem, nHiRow, nR
  1876.  
  1877.    m->nThisOff = 0
  1878.    m->nR = min( m->nRo, m->nElems - m->nTop + 1 )
  1879.    do while m->nThisOff < m->nRo
  1880.       m->nThisRow = m->nDown + m->nThisOff
  1881.       m->nThisElem = m->nTop + m->nThisOff
  1882.       if m->nThisOff < m->nR
  1883.          if m->nThisElem = m->nHigh
  1884.             @ m->nThisRow, m->nRight say m->cBoxL + ;
  1885.             iif( &cArray.[ m->nThisElem, 2], ;
  1886.                         m->cChar, " " ) + m->cBoxR color &cHigh.
  1887.             @ m->nThisRow, col() say ;
  1888.               left( &cArray.[ m->nThisElem, 1 ] ;
  1889.                     + space( m->nLength ), m->nLength ) color &cHigh.
  1890.                  m->nHiRow = m->nThisRow
  1891.          else
  1892.             @ m->nThisRow, m->nRight say m->cBoxL + ;
  1893.                       iif( &cArray.[ m->nThisElem, 2], ;
  1894.                       m->cChar, " " ) + m->cBoxR color &cNorm.
  1895.             @ m->nThisRow, col() say ;
  1896.                left( &cArray.[ m->nThisElem, 1 ] ;
  1897.                       + space( m->nLength ), m->nLength ) color &cNorm.
  1898.          endif
  1899.       else
  1900.          @ m->nThisRow, m->nRight say space( m->nCkCol + ;
  1901.                         len( m->cBoxR ) + m->nLength )
  1902.       endif
  1903.       m->nThisOff = m->nThisOff + 1
  1904.    enddo
  1905.    @ m->nLast, m->nLPad say " Done " color &cQuit.
  1906.    @ m->nLast, m->nRPad say "Cancel" color &cQuit.
  1907.    @ m->nHiRow, m->nCkCol say ""             
  1908.  
  1909. RETURN
  1910. *-- EoP: SMultPick
  1911.  
  1912. FUNCTION YesQuit
  1913. *-----------------------------------------------------------------------
  1914. *-- Programmer..: Jay Parsons  (CIS: 72662,1302)
  1915. *-- Date........: 02/24/1993
  1916. *-- Notes.......: Asks whether to quit and cancel changes; does so if 
  1917. *--               yes.
  1918. *-- Written for.: dBASE IV, Version 1.5.
  1919. *-- Rev. History: 02/24/1993 -- Original Release
  1920. *-- Calls.......: YnMouse()            Function in SCREENS.PRG
  1921. *-- Called by...: Multipick
  1922. *-- Usage.......: YesQuit()
  1923. *-- Example.....: ? Yesquit()
  1924. *-- Parameters..: None
  1925. *-- Returns.....: Logical, .T. for "Yes" or .F. for "No"
  1926. *-- Side effects: If "Yes", restores cArray[ , 2 ] values from cTemp
  1927. *-----------------------------------------------------------------------
  1928.  
  1929.    private nX, lRet
  1930.  
  1931.    lRet = YnMouse( "","Do you wish to restore", ;
  1932.           "the original selection","and leave this routine?" )
  1933.    if m->lRet
  1934.       m->nX = 1
  1935.       do while m->nX <= m->nElems
  1936.          &cArray.[ m->nX, 2 ] = cTemp[ m->nX ]
  1937.          m->nX = m->nX + 1
  1938.       enddo
  1939.    endif
  1940.  
  1941. RETURN m->lRet
  1942. *-- EoF: YesQuit()
  1943.  
  1944. FUNCTION YnMouse
  1945. *-----------------------------------------------------------------------
  1946. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  1947. *-- Date........: 02/28/1993
  1948. *-- Notes.......: Returns .T. or .F. answer to question without leaving
  1949. *--               mouse droppings.  Will not respond to left arrow 
  1950. *--               properly unless set( "ESCAPE" ) is off.
  1951. *--               *******************************
  1952. *--               **** REQUIRES MUSCLICK.BIN ****
  1953. *--               *******************************
  1954. *-- Written for.: dBASE IV, Version 1.5.
  1955. *-- Rev. History: 02/23/93 - original function
  1956. *--               02/28/93 - revised to support right and left arrows
  1957. *-- Calls.......: HighColors()     Function in COLOR.PRG
  1958. *--               Center           Procedure in PROC.PRG (if centering)
  1959. *-- Called by...: Any
  1960. *-- Usage.......: YnMouse( <cColors>, <cP1> [, <cP2>...] [,<lYes>] )
  1961. *-- Example.....: ? YnMouse( "", "Are you sure?" )
  1962. *-- Parameters..: cColors   -   String, either blank or holding desired
  1963. *--                             colors as standard ;
  1964. *--                             [,enhanced [,border ]]
  1965. *--               cP<n>     -   One or more strings of prompt 
  1966. *--                             characters. < only 7 may be passed as 
  1967. *--                             literals using dBASE IV 1.5 >.  They 
  1968. *--                             will be printed one below the other.  
  1969. *--                             There may not in any event be more than 
  1970. *--                             the number of useable screen rows less 
  1971. *--                             6; the parameters line will have to be 
  1972. *--                             changed to use more than 20.
  1973. *--                             As furnished, the justification of the
  1974. *--                             prompt strings is flush left.  To center
  1975. *--                             them, see the commented lines in the 
  1976. *--                             code. Centering uses the Center 
  1977. *--                             procedure in PROC.PRG.
  1978. *--               lYes      -   A logical .T. if the default answer is 
  1979. *--                             "Yes" This must be the last parameter,
  1980. *--                             but it may follow any number of prompt
  1981. *--                             lines.
  1982. *-- Returns.....: Logical, .T. for "Yes" or .F. for "No"
  1983. *-----------------------------------------------------------------------
  1984.  
  1985.    parameters cColors, cP01, cP02, cP03, cP04, cP05, cP06, cP07, ;
  1986.               cP08, cP09, cP10, cP11, cP12, cP13, cP14, cP15, ;
  1987.               cP16, cP17, cP18, cP19, cP20, lYes
  1988.  
  1989.    private cYn, nX, lY, nParams, nRows, nCols, cWhich, nBot, ;
  1990.            nTop, nLeft
  1991.    private cColrs, cPads, nLpad, nRpad, lRet, nScr
  1992.  
  1993.    * obtain number of prompts, and default answer if provided
  1994.    m->nParams = pcount() - 1
  1995.    m->lY = .F.
  1996.  
  1997.    * if we have 22 parameters, last must be the default answer
  1998.    if m->nParams = 21
  1999.       m->lY = m->lYes
  2000.       * otherwise look at the last parameter's type--if it is 
  2001.       * logical that's the default answer and not a prompt
  2002.    else
  2003.       m->cWhich = "cP" + right( str( 100 + m->nParams ), 2 )
  2004.       if type( m->cWhich ) = "L"
  2005.          m->lY = &cWhich.
  2006.          m->nParams = m->nParams - 1
  2007.       endif
  2008.    endif
  2009.  
  2010.    * we need six rows for top and bottom borders, space before 
  2011.    * prompts, space after prompts, yes/no pads and space after 
  2012.    * them
  2013.    m->nRows = m->nParams + 6
  2014.    m->nScr = iif( "43" $ set( "DISPLAY" ), 43, 25 )
  2015.  
  2016.    * don't overwrite messages, status or scoreboard
  2017.    m->nBot = m->nScr - 2
  2018.    m->nTop = 0
  2019.    if set( "STATUS" ) = "ON"
  2020.       m->nBot = m->nBot - 2
  2021.    else
  2022.       if set( "SCOREBOARD" ) = "ON"
  2023.          m->nTop = 1
  2024.       endif
  2025.    endif
  2026.    if m->nRows > m->nBot - m->nTop
  2027.       activate screen
  2028.       ? "Too many prompt lines for screen size - aborting"
  2029.       wait
  2030.       cancel
  2031.    endif
  2032.  
  2033.    * find longest prompt line and window width it requires 
  2034.    * including a space at both ends
  2035.    m->nX = 1
  2036.    m->nCols = 13           && 11 spaces for the pads, 2 for border
  2037.    do while m->nX <= m->nParams
  2038.       m->cWhich = "cP" + right( str( 100 + m->nX ), 2 )
  2039.       m->nCols = max( m->nCols, len( trim( &cWhich. ) ) + 2 )
  2040.       m->nX = m->nX + 1
  2041.    enddo
  2042.  
  2043.    * round up to even number of columns in order to center the 
  2044.    * window
  2045.    m->nCols = 2 * ceiling( m->nCols/ 2 )
  2046.    if m->nCols > 80
  2047.       activate screen
  2048.       ? "Prompts are too long for screen - aborting"
  2049.       wait
  2050.       cancel
  2051.    endif
  2052.  
  2053.    * calculate screen row of top and bottom of centered window
  2054.    m->nTop = max( m->nTop, int( ( m->nScr - m->nRows ) / 2 ) )
  2055.    m->nBot = m->nTop + m->nRows
  2056.  
  2057.    * and screen column of left edge
  2058.    m->nLeft = 39 - m->nCols / 2
  2059.  
  2060.    * obtain colors to use, using highlight for pads
  2061.    m->cColrs = iif( "" # m->cColors, m->cColors,;
  2062.                  set( "ATTRIBUTES" ) )
  2063.    if "&" $ m->cColrs
  2064.       m->cColrs = left( m->cColrs, at( "&", m->cColrs ) - 1  )
  2065.    endif
  2066.    m->cPads = HighColors( m->cColrs )
  2067.  
  2068.    * calculate column positions of yes/no pads
  2069.    m->nLPad = int( ( m->nCols - 2 ) / 4 ) - 2
  2070.    m->nRPad = m->nCols - m->nLPad - 6
  2071.  
  2072.    * now open the window and print prompts
  2073.    define window cYn from m->nTop, m->nLeft to m->nBot,;
  2074.                           m->nLeft + m->nCols color &cColrs.
  2075.    activate window cYn
  2076.    m->nX = 1
  2077.    do while m->nX <= m->nParams
  2078.       m->cWhich = "cP" + right( str( 100 + m->nX ), 2 )
  2079.       *  To change from flush left to centered justification of 
  2080.       * the prompts, uncomment the next code line and comment out
  2081.       * the one following.
  2082.       *  You will then need the "Center" procedure in PROC.PRG.
  2083.       *         do Center with nX, nCols, "", &cWhich.
  2084.       @ m->nX, 1 say &cWhich.
  2085.       m->nX = m->nX + 1
  2086.    enddo
  2087.  
  2088.    * print pads
  2089.    @ m->nX + 1, m->nLPad say " Yes " color &cPads.
  2090.    @ m->nX + 1, m->nRPad say "  No " color &cPads.
  2091.    @ m->nX + 1, iif( m->lY, m->nLPad, m->nRPad ) + 2 say ""
  2092.  
  2093.    * and begin a loop that may last forever
  2094.    clear typeahead
  2095.    do while .T.
  2096.       m->nK = inkey()
  2097.       if m->nK = 0
  2098.          loop
  2099.       endif
  2100.       do case
  2101.          case m->nK = 89 .or. m->nK = 121    && 'Y' or 'y'
  2102.              m->lRet = .T.
  2103.              exit
  2104.          case m->nK = 78 .or. m->nK = 110 .or. m->nK = 27   
  2105.                                             && 'N' or 'n' or Esc
  2106.              m->lRet = .F.
  2107.              exit
  2108.          case m->nK = 13 .or. m->nK = 23     && Enter or Ctrl-End
  2109.              m->lRet = m->lY
  2110.              exit
  2111.          case m->nK = 4 .or. m->nK = 19      && right or left arrow
  2112.              m->lY = .not. m->lY
  2113.              @ m->nX + 1, iif( m->lY, m->nLPad, m->nRPad ) + 2 ;
  2114.                                                   say ""
  2115.          case type( "nG_MusClic" ) = "N" .and. m->nK = nG_MusClic
  2116.              store chr(255) to m->cMRow, m->cMCol
  2117.              call MUSCLICK with m->cMRow, m->cMCol
  2118.              m->nMRow = asc( m->cMRow )
  2119.              m->nMCol = asc( m->cMCol )
  2120.              if m->nMRow = m->nTop + m->nX + 2     
  2121.                                     && one more for border
  2122.                 if m->nMCol >= m->nLPad + m->nLeft .and. ;
  2123.                    m->nMCol < m->nLPad + m->nLeft + 5
  2124.                    m->lRet = .T.
  2125.                    exit
  2126.                 endif
  2127.                 if m->nMCol >= m->nRPad + m->nLeft .and. ;
  2128.                    m->nMCol <m->nRPad + m->nLeft + 5
  2129.                    m->lRet = .F.
  2130.                    exit
  2131.                 endif
  2132.              endif
  2133.       endcase
  2134.    enddo
  2135.    deactivate window cYn
  2136.    release window cYn
  2137.  
  2138. RETURN m->lRet
  2139. *-- EoF: YnMouse()
  2140.  
  2141. FUNCTION CWnDecode
  2142. *-----------------------------------------------------------------------
  2143. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  2144. *-- Date........: 02/06/1993
  2145. *-- Notes.......: Returns the numeric value of one of the four codes for
  2146. *--               edges of the window held in a string of the type 
  2147. *--               returned by cWnSize.  These represent numbers of rows 
  2148. *--               or columns.
  2149. *-- Written for.: dBASE IV, Versions 1.0 - 1.5.
  2150. *-- Rev. History: 02/06/1993 -- Original Release
  2151. *-- Calls.......: None
  2152. *-- Called by...: Any
  2153. *-- Usage.......: cWnDecode( <cWnString>,<cEdge>|<nPos> )
  2154. *-- Example.....: m->cWinTop = cWnDecode( cWin, "T" )
  2155. *-- Parameters..: cWnString -   A string returned by CWnSize
  2156. *--               cEdge -       A character parameter beginning with one
  2157. *--                             of the four characters "T","L","B",or 
  2158. *--                             "R",  ( upper or lower case ), OR
  2159. *--               nPos  -       A number indicating the position in the
  2160. *--                             cWnString of the code for the edge.
  2161. *--                             These correspond to the following:
  2162. *--                             Window edge       cEdge       nPos
  2163. *--                               top              T           1
  2164. *--                               left             L           2
  2165. *--                               bottom           B           3
  2166. *--                               right            R           4
  2167. *--                             Either cEdge or nPos must be furnished,
  2168. *--                             not both.
  2169. *-- Returns.....: numeric value of the row or column; -1 for argument
  2170. *--               out of range or cWnString holds garbage or is empty.
  2171. *-----------------------------------------------------------------------
  2172.  
  2173.    parameters cWnString, xEdge
  2174.    private nPos, nRet
  2175.  
  2176.    m->nRet = -1
  2177.    if type( "xEdge" ) = "C"
  2178.       m->nPos = at( upper( left( m->xEdge, 1 ) ), "TLBR" )
  2179.    else
  2180.       if type( "xEdge" ) = "N"
  2181.          m->nPos = m->xEdge
  2182.       endif
  2183.    endif
  2184.    if m->nPos > 0 .and. m->nPos < 5 .and. len( m->cWnString ) = 4
  2185.       m->nRet = asc( substr( m->cWnString, m->nPos, 1 ) ) - 1
  2186.    endif
  2187.    if m->nRet > iif( mod( m->nPos, 2 ) > 0, 43, 80 )
  2188.       m->nRet = -1
  2189.    endif
  2190.  
  2191. RETURN m->nRet
  2192. *-- EoF: CWnDecode
  2193.  
  2194. FUNCTION CWnSize
  2195. *-----------------------------------------------------------------------
  2196. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  2197. *-- Date........: 02/06/1993
  2198. *-- Notes.......: Returns a string of four characters which are chr()
  2199. *--               values of one more each than the top, left, bottom
  2200. *--               and right row and column numbers of the usable surface
  2201. *--               of the current window, or of the screen.  ( one more
  2202. *--               to avoid chr( 0 ) problems )
  2203. *--               Returns "" if unable to find VDCURSOR.BIN
  2204. *--               *******************************
  2205. *--               **** REQUIRES VDCURSOR.BIN ****
  2206. *--               *******************************
  2207. *-- Written for.: dBASE IV, Versions 1.0 - 1.5.
  2208. *-- Rev. History: 02/06/1993 -- Original Release
  2209. *-- Calls.......: nWBsrch()           function included
  2210. *-- Called by...: Any
  2211. *-- Usage.......: cWnSize()
  2212. *-- Example.....: cWin = cWnSize()
  2213. *--               WinBot = asc( substr( cWin, 3 1 ) )
  2214. *-- Parameters..: None
  2215. *-- Returns.....: character string of four chr() values, or "" if error
  2216. *-- Side effects: Called function nWBsrch disables any error trap
  2217. *-----------------------------------------------------------------------
  2218.  
  2219.    private nHi, nLo, nL, cV
  2220.  
  2221.    m->cV = ""
  2222.    if file( "VDCURSOR.BIN" )
  2223.       load VDCURSOR
  2224.       @ 0,0 say ""
  2225.       m->cV = call( "VDCURSOR","  " )
  2226.       release module VDCURSOR
  2227.       * reverse bytes so row comes first
  2228.       m->cV = right( m->cV, 1 ) + left( m->cV, 1 )
  2229.       * this is the first row, and one more than maximum last
  2230.       m->nL = asc( m->cV ) - 1
  2231.       m->nLo = m->nL
  2232.       m->nHi = 44
  2233.       m->cV = m->cV + chr( m->nL + nWBsrch( m->nLo, m->nHi, ;
  2234.                                            "Down" ) + 1 )
  2235.       * first column and one more than last
  2236.       m->nL = asc( substr( m->cV, 2, 1 ) ) - 1
  2237.       m->nLo = m->nL
  2238.       m->nHi = 80
  2239.       m->cV = m->cV + chr( m->nL + nWBsrch( m->nLo, m->nHi, ;
  2240.                    "Across" ) + 1 )
  2241.    endif
  2242.  
  2243. RETURN m->cV
  2244. *-- EoF: CWnSize()
  2245.  
  2246. FUNCTION nWBsrch
  2247. *-----------------------------------------------------------------------
  2248. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  2249. *-- Date........: 02/06/1993
  2250. *-- Notes.......: special binary search routine for window edges
  2251. *-- Written for.: dBASE IV, Versions 1.0 - 1.5.
  2252. *-- Rev. History: 02/06/1993 -- Original Release
  2253. *-- Calls.......: None
  2254. *-- Called by...: cWnSize
  2255. *-- Usage.......: nWBsrch( < nLo >, < nHi >, < cDir > )
  2256. *-- Example.....: Lastrow = nWBsrch( 0, 44, "Down" )
  2257. *-- Parameters..: nLo           Number, top row or left column
  2258. *--               nHi           Number, bottom or right screen edge + 1
  2259. *--               cDir          char, direction - "Down" or "Across"
  2260. *-- Returns.....: number of highest row or column that may be written to
  2261. *-- Side effects: Disables any ON ERROR trap
  2262. *-----------------------------------------------------------------------
  2263.  
  2264.    parameters nLo, nHi, cDir
  2265.    private lToohigh, nTry, cD
  2266.    m->cD = upper( left( m->cDir, 1 ) )
  2267.    do while m->nHi > m->nLo + 1
  2268.       m->lTooHigh = .F.
  2269.       m->nTry = int( ( m->nHi + m->nLo ) / 2 )
  2270.       on error m->lTooHigh = .T.
  2271.       if m->cD $ "DB"
  2272.          @ m->nTry, 0 say ""
  2273.       else
  2274.          @ 0, m->nTry say ""
  2275.       endif
  2276.       if m->lTooHigh
  2277.          m->nHi = m->nTry - 1
  2278.       else
  2279.          m->nLo = m->nTry
  2280.       endif
  2281.    enddo
  2282.    on error
  2283.  
  2284. RETURN m->nLo
  2285. *-- EoF(): nWBsrch
  2286.  
  2287. PROCEDURE SetBorder
  2288. *-----------------------------------------------------------------------
  2289. *-- Programmer..: Kenneth J. Mayer (CIS: 71333,1030)
  2290. *-- Date........: 03/22/1993
  2291. *-- Notes.......: This routine is designed as a front-end for the 
  2292. *--               NEWBORDR routine. It's purpose is to display a sample
  2293. *--               of the specific border from a picklist, and allow the
  2294. *--               user to select one ...
  2295. *-- Written for.: dBASE IV, 2.0
  2296. *-- Rev. History: 03/22/1993
  2297. *-- Calls.......: NEWBORDR()           (Function in SCREEN.PRG)
  2298. *--               SHADOW               (Procedure in PROC.PRG)
  2299. *--               DRAWIT               (Procedure in SCREEN.PRG)
  2300. *-- Called by...: Any
  2301. *-- Usage.......: Do SetBordr with <cColor>
  2302. *-- Example.....: Do SetBordr with cWind1
  2303. *-- Returns.....: None
  2304. *-- Parameters..: cColor = colors for window ...
  2305. *-----------------------------------------------------------------------
  2306.  
  2307.    parameters cColor
  2308.    private cWindow,cBorder,cHigh
  2309.    
  2310.    *-- start off with a few basics
  2311.    save screen to sBorder        && save screen so we can cleanup
  2312.    m->cWindow = window()         && save current window (if any)
  2313.    activate screen         
  2314.    m->cBorder = set("BORDER")    && save current border setting, in
  2315.                                  && case user doesn't select one ...
  2316.    
  2317.    *-- define a window ... note that we're using the current default 
  2318.    *-- border
  2319.    define window wBorder from 5,5 to 15,70 color &cColor.
  2320.    do shadow with 5,5,15,70
  2321.    activate window wBorder
  2322.  
  2323.    m->cHigh = colorbrk(m->cColor,2)
  2324.    @0,40 fill to 8,60 color &cHigh.
  2325.    @0,40 to 8,60 color &cHigh.
  2326.    @4,45 say "Test Area" color &cHigh.
  2327.  
  2328.    *-- create the popup ...
  2329.    define popup pBorders from 0,0
  2330.    define bar  1 of pBorders prompt "A) Double"
  2331.    define bar  2 of pBorders prompt "B) Single"
  2332.    define bar  3 of pBorders prompt "C) Panel (Normal)"
  2333.    define bar  4 of pBorders prompt "D) None"
  2334.    define bar  5 of pBorders prompt "E) Double Top, Single Rest"
  2335.    define bar  6 of pBorders prompt "F) Single Top, Double Rest"
  2336.    define bar  7 of pBorders prompt "G) Single Bottom, Double Rest"
  2337.    define bar  8 of pBorders prompt "H) Double Bottom, Single Rest"
  2338.    define bar  9 of pBorders prompt "I) Double Top/Bottom, Single Rest"
  2339.    define bar 10 of pBorders prompt "J) Single Top/Bottom, Double Rest"
  2340.    define bar 11 of pBorders prompt "K) Single Top/Left, Double Rest"
  2341.    define bar 12 of pBorders prompt "L) Single Top/Right, Double Rest"
  2342.    define bar 13 of pBorders prompt "M) Double Top/Left, Single Rest"
  2343.    define bar 14 of pBorders prompt "N) Double Top/Right, Single Rest"
  2344.    define bar 15 of pBorders prompt "O) Single Left, Double Rest"
  2345.    define bar 16 of pBorders prompt "P) Single Right, Double Rest"
  2346.    define bar 17 of pBorders prompt "Q) Double Left, Single Rest"
  2347.    define bar 18 of pBorders prompt "R) Double Right, Single Rest"
  2348.    define bar 19 of pBorders prompt "S) Panel (Thin)"
  2349.    on popup pBorders do drawit 
  2350.    on selection popup pBorders deactivate popup
  2351.    
  2352.    *-- Now to play inside the window
  2353.    activate popup pBorders   
  2354.  
  2355.    *-- if user didn't select _anything_, then return to original ...
  2356.    if lastkey() = 27 .or. lastkey() = 4 .or. lastkey() = 19
  2357.       set border to &cBorder.
  2358.       m->c_Border = m->cBorder
  2359.    endif
  2360.  
  2361.    *-- cleanup
  2362.    release window wBorder
  2363.    release popup pBorders
  2364.    restore screen from sBorder
  2365.    release screens Border
  2366.  
  2367. RETURN
  2368. *-- EoP: SetBorder
  2369.  
  2370. PROCEDURE DrawIt
  2371. *-----------------------------------------------------------------------
  2372. *-- Programmer..: Kenneth J. Mayer (CIS: 71333,1030)
  2373. *-- Date........: 03/22/1993
  2374. *-- Notes.......: Used specifically with SETBORDER above, to display the
  2375. *--               current selection from the popup.
  2376. *-- Written for.: dBASE IV, 2.0
  2377. *-- Rev. History: 03/22/1993 -- Original
  2378. *-- Calls.......: NewBorder()          Function in SCREEN.PRG
  2379. *-- Called by...: SetBorder            Procedure in SCREEN.PRG
  2380. *-- Usage.......: Do DrawIt
  2381. *-- Example.....: Do DrawIt
  2382. *-- Returns.....: None
  2383. *-- Parameters..: None
  2384. *-----------------------------------------------------------------------
  2385.  
  2386.    m->cStyle = left(Prompt(),1)
  2387.    m->x = NewBorder(m->cStyle)
  2388.    if m->c_Border = "SINGLE"
  2389.       set border to single
  2390.    endif
  2391.    if m->c_Border = "NONE"
  2392.       @0,40 say space(21) color &cHigh.
  2393.       @8,40 say space(21) color &cHigh.
  2394.       m->nCounter = 0
  2395.       do while m->nCounter < 8
  2396.          m->nCounter = m->nCounter + 1
  2397.          @m->nCounter,40 say space(1) color &cHigh.
  2398.          @m->nCounter,60 say space(1) color &cHigh.
  2399.       enddo
  2400.    else
  2401.       @0,40 to 8,60 color &cHigh.
  2402.    endif
  2403.  
  2404. RETURN
  2405. *-- EoP: DrawIt
  2406.  
  2407. FUNCTION Wait4Key
  2408. *-----------------------------------------------------------------------
  2409. *-- Programmer..: Angus Scott-Fleming (CIS: 75500,3223)
  2410. *-- Date........: 08/18/1993
  2411. *-- Notes.......: Time-out option for a READ screen.
  2412. *-- Written for.: dBASE IV, 1.1
  2413. *-- Rev. History: 03/24/1993 -- Original
  2414. *--               08/18/1993 -- Minor change based on problems with
  2415. *--                             negative value keys (like the function
  2416. *--                             keys). Suggested by >Zak<.
  2417. *-- Calls.......: None
  2418. *-- Called by...: Any
  2419. *-- Usage.......: @x,y GET <fieldname> when Wait4Key(<nSeconds>)
  2420. *-- Example.....: @10,10 get m->cTest when Wait4Key(5)
  2421. *-- Returns.....: logical -- .t. if key pressed within nSeconds, .f. if 
  2422. *--                          not.
  2423. *-- Parameters..: nSeconds = how long to wait for time-out.
  2424. *-----------------------------------------------------------------------
  2425.  
  2426.    parameters nSeconds
  2427.    private nDummy, lKeyPressd
  2428.    
  2429.    m->nDummy = inkey(m->nSeconds)
  2430.    if m->nDummy = 0                 && no keypress
  2431.       *-- abort the read
  2432.       keyboard chr(27)              && send an <Esc>
  2433.       m->lKeyPressd = .f.
  2434.    else
  2435.       *-- keyboard the character
  2436.       keyboard chr(max(0,m->nDummy))
  2437.       m->lKeyPressd = .t.
  2438.    endif
  2439.  
  2440. RETURN m->lKeyPressd
  2441. *-- EoF: Wait4Key()
  2442.  
  2443. PROCEDURE JazFill
  2444. *-----------------------------------------------------------------------
  2445. *-- Programmer..: Rick Price (HAMMETT)
  2446. *-- Date........: 05/15/1993
  2447. *-- Notes.......: Original is used to fill the screen with chr(176) from
  2448. *--               the middle out. Thiss is modified (see below) to work
  2449. *--               on a specific portion of the screen.
  2450. *-- Written for.: dBASE IV, 1.1
  2451. *-- Rev. History: 05/24/1991 -- Original release
  2452. *--               05/24/1993 -- Updated by Peter Stevens as an 
  2453. *--                     adaptation of JAZCLEAR -- This version can be 
  2454. *--                     used to fill a section of the screen with the 
  2455. *--                     ASCII chr(176) character.
  2456. *-- Calls.......: None
  2457. *-- Called by...: Any
  2458. *-- Usage.......: do jazfill with <nBegRow>,<nBegCol>,<nEndRow>,;
  2459. *--                               <nEndCol>,<nSpeed>,<nColoSet>
  2460. *-- Examples....: do jazfill with 4,1,23,78,5
  2461. *-- Returns.....: None
  2462. *-- Parameters..: nBegRow  = Starting Row
  2463. *--               nBegCol  = Starting Column
  2464. *--               nEndRow  = Ending Row (Bottom Right)
  2465. *--               nEndCol  = Ending Column (Bottom Right)
  2466. *--               nSpeed   = How fast?
  2467. *--               nColoSet = What colors to fill with
  2468. *--                          1 = purple/white
  2469. *--                          2 = yellow/black
  2470. *--                          3 = cyan/blue
  2471. *-----------------------------------------------------------------------
  2472.  
  2473.    parameters nBegRow,nBegCol,nEndRow,nEndCol,nSpeed,nColoSet
  2474.  
  2475.    private nWinR1, nWinR2, nWinC1, nWinC2, nStep, mnWinC1, mnWinC2, ;
  2476.            mnWinR1, mnWinR2, nStep, nTmpAdjR, nTmpAdjC, nAdjRow, nAdjCol
  2477.    private nColLeft, nColRite, nRowTop, nRowBot, nWinR1a, nBlk_no
  2478.    private sSBar, sShade
  2479.  
  2480.    m->nWinR1 = m->nBegRow          && row 1
  2481.    m->nWinR2 = m->nEndRow          && row 2
  2482.    m->nWinC1 = m->nBegCol          && column 1
  2483.    m->nWinC2 = m->nEndCol          && column 2
  2484.    m->nStep  = m->nSpeed           && bursting speed(lower no. 
  2485.                                    && for small windows)
  2486.   
  2487.    * set choice of colors for the fill
  2488.    do CASE
  2489.       CASE m->nColoSet = 1
  2490.            m->sShade = "RB+/W"
  2491.       CASE m->nColoSet = 2
  2492.            m->sShade = "RG+/N"
  2493.       CASE m->nColoSet = 3
  2494.            m->sShade = "BG+/B"
  2495.    endcase
  2496.  
  2497.    * set starting point
  2498.    m->mnWinC1 = int((m->nWinC2-m->nWinC1)/2)+m->nWinC1
  2499.    m->mnWinC2 = m->mnWinC1+1
  2500.    m->mnWinR1 = int((m->nWinR2-m->nWinR1)/2)+m->nWinR1
  2501.    m->mnWinR2 = m->mnWinR1+1
  2502.    
  2503.    ** Adjust step offset values: nColOff & nRowOff
  2504.    ** Vertical steps: nWinR1-nWinR1
  2505.    m->nTmpAdjR = int((m->nWinR2 - m->nWinR1)/2)
  2506.    m->nTmpAdjC = int((m->nWinC2 - m->nWinC1)/2)
  2507.    
  2508.    nAdjRow = ;
  2509.       iif(m->nTmpAdjC > m->nTmpAdjR, m->nTmpAdjR/m->nTmpAdjC,1);
  2510.           * m->nStep
  2511.    
  2512.    nAdjCol = ;
  2513.       iif(m->nTmpAdjR > m->nTmpAdjC, m->nTmpAdjC/m->nTmpAdjR,1);
  2514.           * m->nStep
  2515.    
  2516.    m->nColleft = m->nWinC1
  2517.    m->nColrite = m->nWinC2
  2518.    m->nRowTop = m->nWinR1
  2519.    m->nRowBot = m->nWinR2
  2520.    m->nWinC1 = m->mnWinC1
  2521.    m->nWinC2 = m->mnWinC2
  2522.    m->nWinR1 = m->mnWinR1
  2523.    m->nWinR2 = m->mnWinR2
  2524.    do while (m->nWinC1#m->nColLeft .or. m->nWinC2#m->nColRite .or. ;
  2525.       m->nWinR1 # m->nRowTop .or. m->nWinR2 # m->nRowBot)
  2526.       
  2527.       * Adjust coordim->nAtes for the clear (moving out from the middle)
  2528.       m->nWinR1 = ;
  2529.       m->nWinR1-iif(m->nRowTop<m->nWinR1-nAdjRow,nAdjRow,m->nWinR1-;
  2530.          m->nRowTop)
  2531.       m->nWinR2 = ;
  2532.          m->nWinR2+iif(m->nRowBot>m->nWinR2+nAdjRow,nAdjRow,m->nRowBot-;
  2533.          m->nWinR2)
  2534.       m->nWinC1 = ;
  2535.          m->nWinC1-iif(m->nColLeft<m->nWinC1-nAdjCol,nAdjCol,m->nWinC1-;
  2536.          m->nColLeft)
  2537.       m->nWinC2 = ;
  2538.          m->nWinC2+iif(m->nColRite>m->nWinC2+nAdjCol,nAdjCol,;
  2539.          m->nColRite-m->nWinC2)
  2540.       
  2541.       * Perform the clear
  2542.       m->nWinR1a = m->nWinR1
  2543.       do while m->nWinR1a <= m->nWinR2
  2544.          m->nBlk_no = m->nWinC2-m->nWinC1
  2545.          m->sSBAR = replicate(chr(176),m->nBlk_no)
  2546.          @m->nWinR1a,m->nWinC1 say m->sSBAR color &sSHADE.
  2547.          m->nWinR1a = m->nWinR1a + 1
  2548.       enddo              
  2549.    enddo
  2550.    @ m->nWinR1,m->nWinC1 to m->nWinR2,m->nWinC2 DOUBLE
  2551.    
  2552. RETURN   
  2553. *-- EoP: JazFill
  2554.  
  2555. PROCEDURE Bord3D3
  2556. *-----------------------------------------------------------------------
  2557. *-- Programmer..: Kenneth J. Mayer (CIS: 71333,1030)
  2558. *-- Date........: 05/07/1993
  2559. *-- Notes.......: Designed to take a dialog box that _doesn't_ have a 
  2560. *--               border defined (NONE), and is a grey box (i.e., 
  2561. *--               background is 'W' for color) and give a 3-d border 
  2562. *--               to it ...
  2563. *--               ASSUMPTION: Dialog box is defined in a window ... (not
  2564. *--               using @...FILL TO ... command)
  2565. *-- Written for.: dBASE IV, 1.5
  2566. *-- Rev. History: 03/15/1993 -- Original
  2567. *--               05/07/1993 -- Version to give a single-line border
  2568. *-- Calls.......: COLORBRK()           Function in PROC.PRG
  2569. *--               BackColor()          Function in COLOR.PRG
  2570. *-- Called by...: Any (Specifically YESNO4())
  2571. *-- Usage.......: Do Bord3D3 with <nHeight>,<nWidth>,<cColor>,<nStyle>
  2572. *-- Example.....: Do Bord3D3 with 9,40,cWind1,2
  2573. *-- Returns.....: None
  2574. *-- Parameters..: nHeight  = height of dialog box 
  2575. *--               nWidth   = Width of dialog box
  2576. *--               cColor   = Color settings used for dialog box -- 
  2577. *--                          requires at a minimum the colors for the 
  2578. *--                          text part (i.e, "rg+/r")
  2579. *--               nStyle   = 'Style' of border -- 1 = raised, 2 = inset
  2580. *-----------------------------------------------------------------------
  2581.  
  2582.    parameters nHeight, nWidth, cColor, nStyle
  2583.    private nHeight2, nWidth2
  2584.    
  2585.    m->cBorder = set("BORDER")    && save border setting
  2586.    set border to single          && must be single for this ...
  2587.    
  2588.    *-- figure out colors
  2589.    m->cTextColor = colorbrk(m->cColor,1)
  2590.    m->cBackColor = backcolor(m->cTextColor)
  2591.    m->cHighColor = "W+/"+m->cBackColor
  2592.    m->cShadColor = "N/"+m->cBackColor
  2593.    
  2594.    *-- if style is 1, we do the commands for a 'raised' border
  2595.    *-- if style is 2, we do an 'inset' border
  2596.    if m->nStyle < 1 .or. m->nStyle > 2  && if not 1 or 2 ...
  2597.       m->nStyle = 1
  2598.    endif
  2599.    
  2600.    if m->nStyle = 1
  2601.       *-- Outside of "border"
  2602.       @0,0 to 0,m->nWidth        color &cHighColor.  
  2603.       @0,0 to m->nHeight, 0      color &cHighColor.    
  2604.       @0,0       say chr(218)    color &cHighColor.  
  2605.       @m->nHeight,0 say chr(192) color &cHighColor.       
  2606.       @0,m->nWidth   to m->nHeight,m->nWidth color &cShadColor. 
  2607.       @m->nHeight, 1 to m->nHeight,m->nWidth color &cShadColor. 
  2608.       @0,m->nWidth say chr(191)              color &cShadColor.    
  2609.       @m->nHeight,m->nWidth say chr(217)     color &cShadColor.  
  2610.    
  2611.    
  2612.    else
  2613.       
  2614.       *-- Outside of "border"
  2615.       @0,0 to 0,m->nWidth        color &cShadColor. 
  2616.       @0,0 to m->nHeight, 0      color &cShadColor.          
  2617.       @0,0       say chr(218)    color &cShadColor.      
  2618.       @m->nHeight,0 say chr(192) color &cShadColor.       
  2619.       @0,m->nWidth   to m->nHeight,m->nWidth color &cHighColor. 
  2620.       @m->nHeight, 1 to m->nHeight,m->nWidth color &cHighColor. 
  2621.       @0,m->nWidth say chr(191)              color &cHighColor.        
  2622.       @m->nHeight,m->nWidth say chr(217)     color &cHighColor.  
  2623.    
  2624.    endif
  2625.    
  2626.    *-- reset border
  2627.    set border to &cBorder.
  2628.  
  2629. RETURN
  2630. *-- EoP: Bord3D3
  2631.  
  2632. PROCEDURE Bord3D4
  2633. *-----------------------------------------------------------------------
  2634. *-- Programmer..: Kenneth J. Mayer (CIS: 71333,1030)
  2635. *-- Date........: 05/07/1993
  2636. *-- Notes.......: This variation on BORD3D was written to deal with 
  2637. *--               items that are "filled", rather than windows, that 
  2638. *--               have a set edge. This one requires that the actual 
  2639. *--               coordinates get passed to it. This one is a single-
  2640. *--               line version of BORD3D2.
  2641. *-- Written for.: dBASE IV, 1.5
  2642. *-- Rev. History: 03/18/1993 -- Original
  2643. *--               05/07/1993 -- Single-Line Version
  2644. *-- Calls.......: None
  2645. *-- Called by...: Any
  2646. *-- Usage.......: Do Bord3D4 with <nTop>,<nLeft>,<nBottom>,<nRight>,;
  2647. *--                               <cColor>,<nStyle>
  2648. *-- Example.....: Do Bord3d4 with 0,15,4,60,cColor,1
  2649. *-- Returns.....: None
  2650. *-- Parameters..: nTop    = top row
  2651. *--               nLeft   = Left column
  2652. *--               nBottom = Bottom Row
  2653. *--               nRight  = Right Column
  2654. *--               cColor  = Color of area being filled
  2655. *--               nStyle  = type of 3-d border (1 = Raised, 2 = Inset)
  2656. *-----------------------------------------------------------------------
  2657.  
  2658.    parameters nTop,nLeft,nBottom,nRight,cColor,nStyle
  2659.  
  2660.    *-- deal with border ...
  2661.    m->cBorder = set("BORDER")
  2662.    
  2663.    *-- figure out colors
  2664.    m->cTextColor = colorbrk(m->cColor,1)
  2665.    m->cBackColor = backcolor(m->cTextColor)
  2666.    m->cHighColor = "W+/"+m->cBackColor
  2667.    m->cShadColor = "N/"+m->cBackColor
  2668.    
  2669.    *-- if style is 1, we do the commands for a 'raised' border
  2670.    *-- if style is 2, we do an 'inset' border
  2671.    if m->nStyle < 1 .or. m->nStyle > 2  && if not 1 or 2 ...
  2672.       m->nStyle = 1
  2673.    endif
  2674.    
  2675.    if m->nStyle = 1
  2676.       *-- RAISED Border
  2677.       *-- Outside of "border"
  2678.       @m->nTop,m->nLeft to m->nTop,m->nRight   color &cHighColor. 
  2679.       @m->nTop,m->nLeft to m->nBottom,m->nLeft color &cHighColor.   
  2680.       @m->nTop,m->nLeft say chr(218)           color &cHighColor. 
  2681.       @m->nBottom,m->nLeft say chr(192)        color &cHighColor. 
  2682.       @m->nTop,m->nRight to m->nBottom,m->nRight     color &cShadColor. 
  2683.       @m->nBottom,m->nLeft+1 to m->nBottom,m->nRight color &cShadColor
  2684.       @m->nTop,m->nRight say chr(191)                color &cShadColor. 
  2685.       @m->nBottom,m->nRight say chr(217)             color &cShadColor. 
  2686.    
  2687.    else
  2688.       *-- RECESSED Border
  2689.       *-- Outside of "border"
  2690.       @m->nTop,m->nLeft to m->nTop,m->nRight   color &cShadColor. 
  2691.       @m->nTop,m->nLeft to m->nBottom,m->nLeft color &cShadColor.   
  2692.       @m->nTop,m->nLeft say chr(218)           color &cShadColor. 
  2693.       @m->nBottom,m->nLeft say chr(192)        color &cShadColor. 
  2694.       @m->nTop,m->nRight to m->nBottom,m->nRight     color &cHighColor. 
  2695.       @m->nBottom,m->nLeft+1 to m->nBottom,m->nRight color &cHighColor. 
  2696.       @m->nTop,m->nRight say chr(191)                color &cHighColor. 
  2697.       @m->nBottom,m->nRight say chr(217)             color &cHighColor. 
  2698.    
  2699.    endif
  2700.    
  2701.    *-- reset border
  2702.    set border to &cBorder.
  2703.    
  2704. RETURN
  2705. *-- EoP: Bord3D4
  2706.  
  2707. PROCEDURE NewBack
  2708. *-----------------------------------------------------------------------
  2709. *-- Programmer..: Kenneth J. Mayer (CIS: 71333,1030)
  2710. *-- Date........: 06/11/1993
  2711. *-- Notes.......: Based on some ideas from Mike Irwin's presentation at 
  2712. *--               the 4th Annual Borland International Conference (Tips
  2713. *--               and Tricks), this routine will provide a textured 
  2714. *--               background surface using the current colors for the 
  2715. *--               background, and three ascii high order characters 
  2716. *--               (176,177,178). It is able to handle different 
  2717. *--               screen sizes (i.e., 25 line, 43 line and 50 line).
  2718. *--               WARNING: This routine assumes that the status line 
  2719. *--               is turned off.
  2720. *-- Written for.: dBASE IV, 1.5
  2721. *-- Rev. History: 06/11/1993 -- Original
  2722. *-- Calls.......: None
  2723. *-- Called by...: Any
  2724. *-- Usage.......: do NewBack
  2725. *-- Example.....: do NewBack
  2726. *-- Returns.....: None
  2727. *-- Parameters..: None
  2728. *-----------------------------------------------------------------------
  2729.    
  2730.    private cScrType, nScrHeight, cString, nTimes, nTop, nBottom, nCount
  2731.    m->cString = replicate("∞±≤",80)  && 240 = 80 characters
  2732.                                   && times three lines
  2733.    m->cString2 = replicate("∞±≤",26)+"∞±"  && bottom row ...
  2734.    m->cString3 = replicate("≤∞±",26)+"≤±"  && bottom for 50 line mode
  2735.  
  2736.    *-- get the screen height -- if we have a mono monitor, it is, by 
  2737.    *-- definition, 25 lines.
  2738.    m->cScrType = set("DISPLAY")
  2739.    if m->cScrType = "MONO"
  2740.       m->nScrHeight = 25
  2741.    else
  2742.       m->nScrHeight = val(right(m->cScrType,2))
  2743.    endif
  2744.    m->nScreen = m->nScrHeight
  2745.    m->nScrHeight = m->nScrHeight - 1  && start at 0, remember!
  2746.    
  2747.    *-- now, how to deal with the display? We want to do a routine where 
  2748.    *-- we display one set at the top, one at the bottom, and back to 
  2749.    *-- the top. This tricks the eye into thinking that it's happening 
  2750.    *-- all at once, rather than top to bottom ...
  2751.    if m->nScrHeight/3 = int(m->nScrHeight/3)
  2752.       m->nTimes = m->nScrHeight/3
  2753.    else
  2754.       m->nScrHeight = m->nScrHeight - 1
  2755.       if m->nScrHeight/3 = int(m->nScrHeight/3)
  2756.          m->nTimes = m->nScrHeight/3
  2757.       else
  2758.          m->nScrHeight = m->nScrHeight - 1
  2759.          m->nTimes = m->nScrHeight/3
  2760.       endif
  2761.    endif
  2762.    m->nTimes = m->nTimes / 2
  2763.    
  2764.    *-- Now for a display loop ... 
  2765.    m->nTop = 0
  2766.    m->nBottom = m->nScrHeight - 3
  2767.    m->nCount = 0
  2768.    do while m->nCount < m->nTimes
  2769.       m->nCount = m->nCount + 1
  2770.       @   m->nTop,0 say m->cString
  2771.       @m->nBottom,0 say m->cString
  2772.       m->nTop    = m->nTop + 3
  2773.       m->nBottom = m->nBottom - 3
  2774.    enddo
  2775.    do case
  2776.       case m->nScreen = 25 .or. m->nScreen = 43
  2777.          @m->nScreen-1,0 say m->cString2
  2778.       case m->nScreen = 50
  2779.          @48,0 say m->cString2
  2780.          @49,0 say m->cString3
  2781.    endcase
  2782.    
  2783. RETURN
  2784. *-- EoP: NewBack
  2785.  
  2786. FUNCTION Bevel
  2787. *-----------------------------------------------------------------------
  2788. *-- Programmer..: Adam L. Menkes (Borland)
  2789. *-- Date........: 04/xx/1993
  2790. *-- Notes.......: Taken from the April/May issue of dTech News.
  2791. *--               This routine will create a 'beveled' area on the 
  2792. *--               screen (3-d border). This is done by passing two 
  2793. *--               parameters, and using the @/SAY for the starting 
  2794. *--               coordinates. This defaults to the Borland "chiseled
  2795. *--               steel" look. If you want other colors, you will need
  2796. *--               to modify this routine (or use a different one, such
  2797. *--               as BORD3D or BORD3D2 in PROC.PRG).
  2798. *--               Quoting from the article:
  2799. *--                 "Placing text in the screen should be done before 
  2800. *--               the function is called. This way, the background color
  2801. *--               can blend in, though the text colors will become 
  2802. *--               black. If you do not want the text to display in 
  2803. *--               black but still want it to blend, determine the dull
  2804. *--               color color (which is the value of cClrBack in the 
  2805. *--               program) and @...SAY the text with <your color>/
  2806. *--               <dull color>. See the [code] for getting colors, and
  2807. *--               use the code for getting cClrBack. For example,
  2808. *--               if your colors are "W+/B", the background color will 
  2809. *--               be "W" ("+" is stripped). Assuming this was stored to
  2810. *--               the variable cBackColor and you wanted red text, the 
  2811. *--               syntax would look like:
  2812. *--                       @ 5, 5 say bevel(10,60)
  2813. *--                       @10,27 say "Hello World" COLOR R/&cBackColor.
  2814. *--                 "Another feature of the UDF is the shadowing. The 
  2815. *--               shadowing effect is evened out by using 1/2 height 
  2816. *--               shadowing on the horizontal surface and the upper 
  2817. *--               right hand corner. This gives it a more natural 
  2818. *--               appearance than trying to even out the aspect ratio 
  2819. *--               by using full height shadowing for the bottom,
  2820. *--               and double for the right edge. This will not work 
  2821. *--               properly if you shade the entire background with a 
  2822. *--               character (chr(178) as an example."
  2823. *-- Written for.: dBASE IV, 2.0 (should work with earlier versions)
  2824. *-- Rev. History: 04/xx/1993 -- Original
  2825. *-- Calls.......: None
  2826. *-- Called by...: Any
  2827. *-- Usage.......: @<x>,<y> say Bevel(<nBottom>,<nRight>)
  2828. *-- Example.....: @5,10 say bevel(10,60)
  2829. *-- Returns.....: nul
  2830. *-- Parameters..: nBottom = bottom row
  2831. *--               nRight  = right column
  2832. *-----------------------------------------------------------------------
  2833.  
  2834.    parameters nBottom, nRight
  2835.    private nTop, nLeft, nBottom, nRight, cAttr, cBorder, cNormFore, ;
  2836.            cEnh, cClrFore, cClrBack, cClrShad
  2837.    
  2838.    m->nTop    = row()
  2839.    m->nLeft   = col()
  2840.    m->nBottom = iif(pcount() < 1, max(25,val(right(set("DISPLAY"),;
  2841.                    2))) - 2, m->nBottom+m->nTop) && maximum: lastrow - 1
  2842.    m->nRight   = iif(pcount() < 2, 78, m->nLeft+m->nRight) && maximum 78
  2843.    
  2844.    *-- get current color settings for highlighting
  2845.    m->cAttr     = set("ATTRIBUTES")
  2846.    m->cEnh      = substr(m->cAttr,at(",",m->cAttr)+1,;
  2847.                       at(",",m->cAttr,2)-1-at(",",m->cAttr))
  2848.    m->cNormBack = substr(m->cAttr,at("/",m->cAttr)+1,;
  2849.                      at(",",m->cAttr)-1-at("/",m->cAttr))
  2850.    m->cClrFore  = left(m->cAttr,at("/",m->cAttr)-1)
  2851.    m->cClrFore  = m->cClrFore+iif("+"$m->cClrFore,"","+")
  2852.    m->cClrFore  = iif(m->cClrFore = "N+","W+",m->cClrFore)
  2853.    m->cClrBack  = left(m->cClrFore,len(m->cClrFore) - ;
  2854.                     iif(right(m->cClrFore,1) = "+",1,0))
  2855.    m->cClrShad  = "N"
  2856.    m->cBorder =  set("BORDER")
  2857.    
  2858.    *-- fill region with color
  2859.    @m->nTop, m->nLeft -1 fill to m->nBottom, m->nRight   ;
  2860.                                             color /&cClrBack.
  2861.    
  2862.    *-- draw shadow
  2863.    @m->nTop+1,m->nRight+1 fill to m->nBottom,m->nRight+1 ;
  2864.                                             color /&cClrShad.
  2865.    @m->nTop,m->nRight+1 say chr(220)        color &cClrShad./&cNormBack.
  2866.    @m->nBottom+1,m->nLeft+1 say replicate(chr(223),m->nRight-;
  2867.                                             m->nLeft+1);
  2868.                                             color &cClrShad./&cNormBack.
  2869.    
  2870.    *-- Draw outer lines and highlights
  2871.    @m->nTop+1,m->nLeft    to m->nBottom - 1,m->nLeft  ;  
  2872.                                             color &cClrFore./&cClrBack.
  2873.    @m->nBottom,m->nLeft+1 to m->nBottom,m->nRight - 1;   
  2874.                                            color &cClrShad./&cClrBack.
  2875.    @m->nTop,m->nLeft+1    to m->nTop,m->nRight - 1  ;    
  2876.                                            color &cClrFore./&cClrBack.
  2877.    @m->nTop+1,m->nRight   to m->nBottom-1,m->nRight ;
  2878.                                            color &cClrShad./&cClrBack.
  2879.    
  2880.    *-- Draw inner lines and highlights
  2881.    @m->nTop+2,m->nLeft+2    to m->nBottom-2,m->nLeft+2  ;
  2882.                                            color &cClrShad./&cClrBack.
  2883.    @m->nBottom-1,m->nLeft+3 to m->nBottom-1,m->nRight-3 ;
  2884.                                            color &cClrFore./&cClrBack.
  2885.    @m->nTop+1,m->nLeft+3    to m->nTop+1,m->nRight-3    ;
  2886.                                            color &cClrShad./&cClrBack.
  2887.    @m->nTop+2,m->nRight-2   to m->nBottom-2,m->nRight-2 ;
  2888.                                            color &cClrFore./&cClrBack.
  2889.    
  2890.    *-- Draw outer corners
  2891.    @m->nTop,m->nLeft     say chr(218)      color &cClrFore./&cClrBack.
  2892.    @m->nBottom,m->nLeft  say chr(192)      color &cClrFore./&cClrBack.
  2893.    @m->nTop,m->nRight    say chr(191)      color &cClrShad./&cClrBack.
  2894.    @m->nBottom,m->nRight say chr(217)      color &cClrShad./&cClrBack.
  2895.    
  2896.    *-- Draw inner corners
  2897.    @m->nTop+1,m->nLeft+2     say chr(218)  color &cClrShad./&cClrBack.
  2898.    @m->nBottom-1,m->nLeft+2  say chr(192)  color &cClrShad./&cClrBack.
  2899.    @m->nTop+1,m->nRight-2    say chr(191)  color &cClrFore./&cClrBack.
  2900.    @m->nBottom-1,m->nRight-2 say chr(217)  color &cClrFore./&cClrBack.
  2901.    
  2902.    *-- cleanup
  2903.    set border to &cBorder.
  2904.  
  2905. RETURN ""
  2906. *-- EoF: Bevel()
  2907.  
  2908. FUNCTION Warning
  2909. *----------------------------------------------------------------------
  2910. *-- Programmer..: Angus Scott-Fleming (CIS: 75500,3223)
  2911. *-- Date........: 10/26/1993
  2912. *-- Notes.......: quick-and-dirty warning message for testing --
  2913. *--               WARNING -- will overwrite bottom of screen ...
  2914. *--               suggest using SAVE/RESTORE Screen ... (KJM)
  2915. *-- Written for.: dBASE IV, 1.5
  2916. *-- Rev. History: 10/26/1993 -- Original
  2917. *-- Calls.......: None
  2918. *-- Called by...: Any
  2919. *-- Usage.......: ? Warning(<c1>[,<c2>,<c3>,<c4>,<c5>])
  2920. *-- Example.....: ? Warning("You dummy!")
  2921. *-- Returns.....: .F.
  2922. *-- Parameters..: Up to five character strings to display at EoScreen
  2923. *----------------------------------------------------------------------
  2924.  
  2925.    parameters cM1, cM2, cM3, cM4, cM5
  2926.    private cDevice, lConsole, lPrintON
  2927.    lConsole = set("console") = "ON"
  2928.    lPrintON = set("printer") = "ON"
  2929.    cDevice  = set("device")
  2930.    set print off
  2931.    set device to screen
  2932.    set console on
  2933.    do case
  2934.       case pcount() = 1
  2935.          @ 23,0 clear to 24,79
  2936.          @ 23,0 say left(m->cM1,79)
  2937.       case pcount() = 2
  2938.          @ 22,0 clear to 24,79
  2939.          @ 22,0 say left(m->cM1,79)
  2940.          @ 23,0 say left(m->cM2,79)
  2941.       case pcount() = 3
  2942.          @ 21,0 clear to 24,79
  2943.          @ 21,0 say left(m->cM1,79)
  2944.          @ 22,0 say left(m->cM2,79)
  2945.          @ 23,0 say left(m->cM3,79)
  2946.       case pcount() = 4
  2947.         @ 20,0 clear to 24,79
  2948.         @ 20,0 say left(m->cM1,79)
  2949.         @ 21,0 say left(m->cM2,79)
  2950.         @ 22,0 say left(m->cM3,79)
  2951.         @ 23,0 say left(m->cM4,79)
  2952.       otherwise
  2953.         * use the first five
  2954.         @ 19,0 clear to 24,79
  2955.         @ 19,0 say left(m->cM1,79)
  2956.         @ 20,0 say left(m->cM2,79)
  2957.         @ 21,0 say left(m->cM3,79)
  2958.         @ 22,0 say left(m->cM4,79)
  2959.         @ 23,0 say left(m->cM5,79)
  2960.    endcase
  2961.    @ 24,0 say "Press any key to continue ... " + chr(7)
  2962.    lDummy = inkey(0)
  2963.    do case
  2964.       case trim(m->cDevice) = "PRINT"
  2965.          set device to PRINT
  2966.       case trim(m->cDevice) = "SCREEN"
  2967.          set device to SCREEN
  2968.       case left(m->cDevice,4) = "FILE"
  2969.          store substr(m->cDevice,5) to cDevice
  2970.          set device to FILE (m->cDevice)
  2971.       otherwise
  2972.          @ 24,0 clear to 24,79
  2973.          @ 24,0 say chr(7) + "UNKNOWN DEVICE IN Warning: "+;
  2974.                              m->cDevice+"  press any key"
  2975.          lDummy = inkey(0)
  2976.    endcase
  2977.    if .not.lConsole
  2978.       set console off
  2979.    endif
  2980.    if lPrintON
  2981.      set printer on
  2982.    endif
  2983.  
  2984. RETURN .F.
  2985. *-- EoF: Warning()
  2986.  
  2987. FUNCTION FRAME
  2988. *-----------------------------------------------------------------------
  2989. *-- Programmer..: Peter Stevens - HMRS (CIS:100114,301)
  2990. *-- Date........: Nov 15th 1993
  2991. *-- Notes.......: Frames up to 3 lines of text with double line border
  2992. *-- Written for.: dBASE IV 1.5 (All?)
  2993. *-- Rev. History: 09/05/1993 - Original program 
  2994. *--               11/09/1993 - Centering option added (Peter Stevens)
  2995. *--               11/15/1993 - Calls SHADE to draw 3D shadow
  2996. *--                            See Function SHADE below
  2997. *-- Calls.......: Shade()
  2998. *-- Called by...: Any
  2999. *-- Usage.......: Frame(nBegRow,nBegCol,nEndRow,nEndCol,"cText1 ",
  3000. *--                   "cText2 ","cText3 ","color1/color2",.T.)
  3001. *-- Example.....: x=Frame(10,10,13,20,"Line # 1 ","Line # 2 ",;
  3002. *--                       "Line # 3 ","RG+/R",.T.)
  3003. *-- Returns.....: ""
  3004. *-- Params......: nBegRow  = start row
  3005. *--               nBegCol  = start col
  3006. *--               nEndRow  = end row
  3007. *--               nEndCol  = end col of fill
  3008. *--               cText1   = TextString1
  3009. *--               cText2   = TextString2
  3010. *--               cText3   = TextString3
  3011. *--               cColor   = colors
  3012. *--               lCenter  = center toggle
  3013. *--               Could be expanded for more lines but remember 
  3014. *--                  the buffer max of 220 chars.
  3015. *--               Each text string should have a _trailing_ space.
  3016. *--               If lCenter is set true the Col params are re-set 
  3017. *--                  _and_ cText1 will set the width of the frame!
  3018. *-----------------------------------------------------------------------
  3019.  
  3020.    parameters nBegRow,nBegCol,nEndRow,nEndCol,cText1,cText2,cText3,;
  3021.               cColor,lCenter
  3022.    private nBegRow,nBegCol,nEndRow,nEndCol,nStartRow,nStartCol,;
  3023.               nLastRow,nLastCol
  3024.  
  3025.    *-- Specify co-ords for SHADE
  3026.    m->nStartRow = m->nBegRow
  3027.    m->nLastRow  = m->nEndRow
  3028.    m->nStartCol = m->nBegCol
  3029.    m->nLastCol  = m->nEndCol
  3030.  
  3031.    m->cText1 = " "+m->cText1    && Adds leading space to m->cText1
  3032.    if len(m->cText2) > 0
  3033.       m->cText2 = " "+m->cText2
  3034.    endif
  3035.    if len(m->cText3) > 0
  3036.       m->cText3 = " "+m->cText3
  3037.    endif
  3038.  
  3039.    if m->lCenter            && reset the col co-ords if 2b center
  3040.       m->nBegCol = (80-len(m->cText1))/2
  3041.       m->nEndCol = (80-len(m->cText1))/2+(len(m->cText1))
  3042.  
  3043.       m->nStartCol = m->nBegCol      && and reset col co-ords for SHADE
  3044.       m->nLastCol  = m->nEndCol
  3045.    endif
  3046.  
  3047.    *-- Clear screen and draw box
  3048.    @ m->nBegRow-1,m->nBegCol-1 clear to m->nEndRow,m->nEndCol
  3049.    @ m->nBegRow-1,m->nBegCol-1  fill to m->nEndRow,m->nEndCol ;
  3050.                                                     color &cColor.
  3051.    @ m->nBegRow-1,m->nBegCol-1 to m->nEndRow,m->nEndCol double ;
  3052.                                                     color &cColor.
  3053.  
  3054.    *-- say first line of text
  3055.    @ m->nBegRow,m->nBegCol say m->cText1 color &cColor.
  3056.  
  3057.    if m->lCenter            && reset the start column for cText2
  3058.       m->nBegCol = (80-len(m->cText2))/2
  3059.    endif
  3060.                   
  3061.    m->nBegRow = m->nBegRow + 1      && jump to next row
  3062.  
  3063.    *-- say second line of text
  3064.    @ m->nBegRow,m->nBegCol say m->cText2 color &cColor.
  3065.  
  3066.    if m->lCenter            && reset the start column for cText3
  3067.       m->nBegCol = (80-len(m->cText3))/2
  3068.    endif
  3069.  
  3070.    m->nBegRow = m->nBegRow + 1      && jump to next row
  3071.  
  3072.    *-- say third line of text
  3073.    @ m->nBegRow,m->nBegCol say m->cText3 color &cColor.
  3074.  
  3075.    *-- Call SHADE to do its stuff
  3076.  
  3077.    x=Shade(m->nStartRow,m->nStartCol,m->nLastRow,m->nLastCol) 
  3078.  
  3079. RETURN "" 
  3080. *-- EoF Frame()
  3081.  
  3082. FUNCTION SHADE
  3083. *----------------------------------------------------------------------
  3084. *-- Programmer..: Peter Stevens (CIS:100114,301)
  3085. *-- Date........: 11/05/1993
  3086. *-- Notes.......: Gives 3D shadow, replaces SHADOWG on LIB201
  3087. *--               This function only draws shaded part on right and bott
  3088. *--               edges of window or popup like an inverted L. The new 
  3089. *--               co-ords are calculated here rather than by the 
  3090. *--               programmer. Text under the shadow shows through.
  3091. *--               Uses the same co-ords as popup or window you want
  3092. *--               shaded
  3093. *-- Written for.: dBASE IV 1.5 (All?)
  3094. *-- Rev. History: 11/05/1993 -- Original program 
  3095. *-- Calls ......: None
  3096. *-- Called by ..: Any
  3097. *-- Usage ......: SHADE(nBegRow,nBegCol,nEndRow,nEndCol)
  3098. *-- Example ....: x=SHADE(10,10,13,20)
  3099. *-- Returns ....: ""
  3100. *-- Params .....: nBegRow = start row
  3101. *--               nBegCol = start col
  3102. *--               nEndRow = end row
  3103. *--               nEndCol = end col 
  3104. *-----------------------------------------------------------------------
  3105.  
  3106.    parameters nBegRow,nBegCol,nEndRow,nEndCol
  3107.    private    nBegRow,nBegCol,nEndRow,nEndCol
  3108.  
  3109.    *-- Recalculate the start positions of the co-ords
  3110.    m->nBegCol = m->nBegCol + 2
  3111.    m->nEndRow = m->nEndRow + 1
  3112.    m->nEndCol = m->nEndCol + 1
  3113.  
  3114.    *-- Draw the vertical line
  3115.    do while m->nBegRow <> m->nEndRow
  3116.       m->nBegRow = m->nBegRow + 1
  3117.       @ m->nBegRow,m->nEndCol fill to m->nBegRow,m->nEndCol+1 color N/GR
  3118.    enddo
  3119.  
  3120.    *-- Draw the horizontal line
  3121.    @ m->nEndRow,m->nBegCol fill to m->nEndRow,m->nEndCol+1 color N/GR
  3122.  
  3123. RETURN ""
  3124. *-- EoF: Shade()
  3125.  
  3126. FUNCTION BurstWin
  3127. *-----------------------------------------------------------------------
  3128. *-- Programmer..: Peter Stevens (CIS:100114,301)
  3129. *-- Date........: 11/28/1993
  3130. *-- Notes.......: Draws a bursting pseudo-window with chr(177) in-fill
  3131. *--               The speed parameter determines the rate at which
  3132. *--               horizontal expansion of the window occurs.
  3133. *-- Written for.: dBASE IV 1.5 (All?)
  3134. *-- Rev. History: 11/28/1993 - Original program 
  3135. *-- Calls.......: None
  3136. *-- Called by...: Any
  3137. *-- Usage.......: BurstWin(<nBeginRow>,<nBeginCol>,<nEndRow>,;
  3138. *--                            <nEndCol>,<nStep>,<cColor>)
  3139. *-- Example.....: x=BurstWin(10,10,13,20,2,"GR+/GR")
  3140. *-- Returns.....: ""
  3141. *-- Parameters..: nBeginRow = Starting Row
  3142. *--               nBeginCol = Starting Column
  3143. *--               nEndRow   = Ending Row
  3144. *--               nEndCol   = Ending Column
  3145. *--               nStep     = Increment window size by x
  3146. *--               cColor    = Colors (forg/back) of window
  3147. *-----------------------------------------------------------------------
  3148.  
  3149.    parameters nBegRow,nBegCol,nEndRow,nEndCol,nStep,cColor
  3150.  
  3151.    private m->nWidTH,m->nDepth
  3152.    private m->nFirstRow,m->nFirstCol,m->nLastRow,m->nLastCol,nRow
  3153.    private cFill,nFill,m->l_Done1,m->l_Done2,m->l_Done3,m->l_Done4
  3154.  
  3155.    store .F. to m->l_Done1,m->l_Done2,m->l_Done3,m->l_Done4
  3156.    m->nDepth = m->nEndRow - m->nBegRow
  3157.    m->nWidth = m->nEndCol - m->nBegCol
  3158.    
  3159.    *-- Determine the size & starting position of the first window
  3160.    
  3161.    m->nFirstRow = int((m->nBegRow+(m->nDepth/2))-1)
  3162.    m->nFirstCol = m->nBegCol+int((m->nWidth/2)-m->nStep)
  3163.    m->nLastRow  = int((m->nEndRow-(m->nDepth/2))+1)
  3164.    m->nLastCol  = int((m->nBegCol+(m->nWidth/2))+m->nStep)
  3165.    
  3166.    *-- Then draw it
  3167.    @ m->nFirstRow,m->nFirstCol to m->nLastRow,m->nLastCol double ;
  3168.                                                    color &cColor.
  3169.    
  3170.    do while .t.
  3171.  
  3172.       *-- Set the window 1 row higher and expand it by nStep
  3173.       do while .not. m->l_Done1 .or. .not. m->l_Done3
  3174.          if m->nLastRow-m->nFirstRow <= m->nDepth
  3175.             m->nFirstRow = m->nFirstRow - 1
  3176.             if m->nFirstRow < m->nBegRow   && if Row is up too high
  3177.                m->nFirstRow = m->nBegRow   && reset to passed param
  3178.                m->l_Done1 = .T.            && and set l_Done1 as 
  3179.                                            && complete
  3180.             endif
  3181.          endif
  3182.          if m->nLastCol - m->nFirstCol < m->nWidth+m->nStep
  3183.             m->nFirstCol = m->nFirstCol - m->nStep
  3184.             if m->nFirstCol < m->nBegCol   && If Col is too far left
  3185.                m->nFirstCol = m->nBegCol   && reset to passed param
  3186.                m->l_Done3 = .T.            && and l_Done2 is complete
  3187.             endif
  3188.          endif
  3189.  
  3190.          *-- Draw the new window
  3191.          @ m->nFirstRow,m->nFirstCol to m->nLastRow,m->nLastCol double;
  3192.                                                          color &cColor.
  3193.  
  3194.          *-- Then fill it - delete to where shown if running on a slow 
  3195.          *-- machine
  3196.          nRow = m->nFirstRow+1
  3197.          nFill = (m->nLastCol)-(m->nFirstCol+1)
  3198.          do while nRow <= m->nLastRow-1
  3199.             cFill = replicate(chr(177),nFill)
  3200.             @ nRow,m->nFirstCol+1 SAY cFill
  3201.             nRow = nRow + 1
  3202.          enddo
  3203.  
  3204.          *-- Delete to here if applicable
  3205.          exit
  3206.  
  3207.       enddo 
  3208.  
  3209.       *-- Introduce a delay (optional for 486 procs) * out if not reqd.
  3210.       i = inkey(0.08)
  3211.  
  3212.       *-- Set the window 1 row lower and expand it by nStep
  3213.       do while .not. m->l_Done2 .or. .not. m->l_Done4
  3214.          if m->nLastRow-m->nFirstRow <= m->nDepth
  3215.             m->nLastRow = m->nLastRow + 1
  3216.             if m->nLastRow > m->nEndRow   && If Row is too low
  3217.                m->nLastRow = m->nEndRow   && Reset it to passed param
  3218.                m->l_Done2 = .T.           && and l_Done3 is complete
  3219.             endif
  3220.          endif
  3221.          if m->nLastCol - m->nFirstCol < m->nWidth+m->nStep
  3222.             m->nLastCol  = m->nLastCol + m->nStep
  3223.             if m->nLastCol > m->nEndCol   && If Col is too far right
  3224.                m->nLastCol = m->nEndCol   && Reset it to passed param
  3225.                m->l_Done4 = .T.           && and l_Done4 is complete
  3226.             endif
  3227.          endif
  3228.  
  3229.          *-- Draw the new window
  3230.          @ m->nFirstRow,m->nFirstCol to m->nLastRow,m->nLastCol double;
  3231.                                                         color &cColor.
  3232.  
  3233.          *-- And fill it - Delete to where shown if on a slow machine
  3234.          nRow = m->nFirstRow+1
  3235.          nFill = (m->nLastCol)-(m->nFirstCol+1)
  3236.          do while nRow <= m->nLastRow-1
  3237.             cFill = replicate(chr(177),nFill)
  3238.             @ nRow,m->nFirstCol+1 SAY cFill
  3239.             nRow = nRow + 1
  3240.  
  3241.             *-- Delete to here if applicable
  3242.          enddo
  3243.          exit
  3244.       enddo
  3245.  
  3246.       *-- Introduce a small delay as above
  3247.       i = inkey(0.08)
  3248.  
  3249.       *-- Check that window is to specfied size
  3250.       if m->l_Done1 .and. m->l_Done2 .and. m->l_Done3 .and. m->l_Done4
  3251.          exit
  3252.       endif
  3253.  
  3254.    enddo
  3255.  
  3256.    *-- Then fill it - delete to where shown if running on a FAST machine
  3257.    nRow = m->nFirstRow+1
  3258.    nFill = (m->nLastCol)-(m->nFirstCol+1)
  3259.    do while nRow <= m->nLastRow-1
  3260.       cFill = replicate(chr(177),nFill)
  3261.       @ nRow,m->nFirstCol+1 SAY cFill
  3262.       nRow = nRow + 1
  3263.    enddo
  3264.  
  3265.    *-- Delete to here if applicable
  3266.  
  3267.    *-- Optional Extra - Draw a 3-D shadow
  3268.    m->nBegRow = m->nBegRow + 1
  3269.    m->nBegCol = m->nBegCol + 2
  3270.    m->nEndRow = m->nEndRow + 1
  3271.    m->nEndCol = m->nEndCol + 1
  3272.    @ m->nBegRow,m->nEndCol fill to m->nEndRow,m->nEndCol+1 color n+/n
  3273.    @ m->nEndRow,m->nBegCol fill to m->nEndRow,m->nEndCol+1 color n+/n
  3274.  
  3275. RETURN ""
  3276. *-- EoF: BurstWin()
  3277.  
  3278. *-----------------------------------------------------------------------
  3279. *--       Library functions included for convenience
  3280. *-----------------------------------------------------------------------
  3281.  
  3282. FUNCTION NormColors
  3283. *-----------------------------------------------------------------------
  3284. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  3285. *-- Date........: 02/23/1993
  3286. *-- Notes.......: Returns the "normal" portion of a color string
  3287. *-- Written for.: dBASE IV, Version 1.5.
  3288. *-- Rev. History: 02/23/1993 -- Original Release
  3289. *-- Calls.......: None
  3290. *-- Called by...: Any
  3291. *-- Usage.......: NormColors( <cColor> )
  3292. *-- Example.....: ? NormColors( "N/BG,BG+/N,W+/B" )
  3293. *-- Parameters..: cColor    -   String holding colors
  3294. *-- Returns.....: Character, normal color portion of string.
  3295. *-----------------------------------------------------------------------
  3296.  
  3297.    parameters cColor
  3298.    private cRet
  3299.  
  3300.    m->cRet = m->cColor
  3301.    if "," $ m->cRet
  3302.       m->cRet = left( m->cRet, at( ",", m->cRet ) - 1 )
  3303.    endif
  3304.  
  3305. RETURN upper( ltrim( trim ( m->cRet ) ) )
  3306. *-- EoF: NormColors()
  3307.  
  3308. FUNCTION HighColors
  3309. *-----------------------------------------------------------------------
  3310. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  3311. *-- Date........: 02/23/1993
  3312. *-- Notes.......: Returns the "highlight" portion of a color string
  3313. *-- Written for.: dBASE IV, Version 1.5.
  3314. *-- Rev. History: 02/23/1993 -- Original Release
  3315. *-- Calls.......: None
  3316. *-- Called by...: Any
  3317. *-- Usage.......: HighColors( <cColor> )
  3318. *-- Example.....: ? HighColors( "N/BG,BG+/N,W+/B" )
  3319. *-- Parameters..: cColor    -   String holding colors
  3320. *-- Returns.....: Character, highlight color portion of string.
  3321. *--               Returns empty string if no such portion.
  3322. *-----------------------------------------------------------------------
  3323.  
  3324.    parameters cColor
  3325.    private cRet
  3326.  
  3327.    m->cRet = ""
  3328.    if "," $ m->cColor
  3329.       m->cRet = substr( m->cColor, at( ",",m->cColor ) + 1 )
  3330.       if "," $ m->cRet
  3331.          m->cRet = left( m->cRet, at( ",", m->cRet ) - 1 )
  3332.       endif
  3333.    endif
  3334.  
  3335. RETURN upper( ltrim( trim( m->cRet ) ) )
  3336. *-- EoF: HighColors()
  3337.  
  3338. FUNCTION ForeColor
  3339. *-----------------------------------------------------------------------
  3340. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  3341. *-- Date........: 02/24/1993
  3342. *-- Notes.......: Returns foreground part of color string.
  3343. *-- Written for.: dBASE IV, Version 1.5.
  3344. *-- Rev. History: 02/24/1993 -- Original Release
  3345. *-- Calls.......: None
  3346. *-- Called by...: Any
  3347. *-- Usage.......: ForeColor( <cColor> )
  3348. *-- Example.....: ? ForeColor( "N/BG" )
  3349. *-- Parameters..: cColor    -   String holding color foreground and 
  3350. *--                             background
  3351. *-- Returns.....: Character, string with foreground portion of the color
  3352. *-----------------------------------------------------------------------
  3353.  
  3354.    parameters cColor
  3355.    private cRet
  3356.  
  3357.    m->cRet = upper( trim( ltrim( m->cColor ) ) )
  3358.    if "/" $ m->cRet
  3359.       m->cRet = left( m->cRet, at( "/", m->cRet ) - 1 )
  3360.    endif
  3361.    if "*" $ m->cColor
  3362.       m->cRet = m->cRet + "*"
  3363.    endif
  3364.    if "+" $ m->cColor
  3365.       m->cRet = m->cRet + "+"
  3366.    endif
  3367.  
  3368. RETURN m->cRet
  3369. *-- EoF: ForeColor()
  3370.  
  3371. PROCEDURE Center
  3372. *-----------------------------------------------------------------------
  3373. *-- Programmer..: Miriam Liskin
  3374. *-- Date........: 05/24/1991
  3375. *-- Notes.......: Centers text on the screen with @says
  3376. *-- Written for.: dBASE IV, 1.1
  3377. *-- Rev. History: This and all other procedures/functions listed in this
  3378. *--               file attributed to Miriam Liskin came from "Liskin's
  3379. *--               Programming dBASE IV Book". Very good, worth the money
  3380. *-- Calls.......: None
  3381. *-- Called by...: Any
  3382. *-- Usage.......: do center with <nLine>,<nWidth>,"<cColor>","<cText>"
  3383. *-- Example.....: do center with 5,65,"RG+/GB",;
  3384. *--                      "WARNING! This will blow up!"
  3385. *--                  Note that the color field may be blank: ""
  3386. *-- Returns.....: None
  3387. *-- Parameters..: nLine  = Line or Row for @/Say
  3388. *--               nWidth = Width of screen
  3389. *--               cColor = Colors to be used ("Forg/Back") 
  3390. *--                          (may be nul "", in order to use the default
  3391. *--                          colors of window/screen)
  3392. *--               cText  = Message to center on screen
  3393. *-----------------------------------------------------------------------
  3394.    
  3395.    parameters nLine,nWidth,cColor,cText
  3396.    private nCol
  3397.    
  3398.    m->nCol = (m->nWidth - len(m->cText)) /2
  3399.    @m->nLine,m->nCol say m->cText color &cColor.
  3400.    
  3401. RETURN
  3402. *-- EoP: Center
  3403.  
  3404. FUNCTION ArrayRows
  3405. *-----------------------------------------------------------------------
  3406. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  3407. *-- Date........: 03/01/1992
  3408. *-- Notes.......: Number of Rows in an array
  3409. *-- Written for.: dBASE IV, 1.1
  3410. *-- Rev. History: 03/01/1992 -- Original Release
  3411. *-- Calls.......: None
  3412. *-- Called by...: Any
  3413. *-- Usage.......: ArrayRows("<aArray>")
  3414. *-- Example.....: n = ArrayRows("aTest")
  3415. *-- Returns.....: numeric
  3416. *-- Parameters..: aArray      = Name of array 
  3417. *-----------------------------------------------------------------------
  3418.  
  3419.    parameters aArray
  3420.    private nHi, nLo, nTrial, nDims
  3421.  
  3422.    m->nLo = 1
  3423.    m->nHi = 1170
  3424.    if type( "&aArray.[ 1, 1 ]" ) = "U"
  3425.      m->nDims = 1
  3426.    else
  3427.      m->nDims = 2
  3428.    endif
  3429.    do while .T.
  3430.       m->nTrial = int( ( m->nHi + m->nLo ) / 2 )
  3431.       if m->nHi < m->nLo
  3432.          exit
  3433.       endif
  3434.       if m->nDims = 1 .and. type( "&aArray[ m->nTrial ]" ) = "U" .or. ;
  3435.          m->nDims = 2 .and. type( "&aArray[ m->nTrial, 1 ]" ) = "U"
  3436.          m->nHi = m->nTrial - 1
  3437.       else
  3438.          m->nLo = m->nTrial + 1
  3439.       endif
  3440.    enddo
  3441.    
  3442. RETURN m->nTrial
  3443. *-- EoF: ArrayRows()
  3444.  
  3445. PROCEDURE ReColor
  3446. *-----------------------------------------------------------------------
  3447. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  3448. *-- Date........: 04/23/1992
  3449. *-- Notes.......: Restores colors to those held in a string of the form
  3450. *--               returned by set("ATTRIBUTE").
  3451. *-- Written for.: dBASE IV, Versions 1.0 - 1.5.
  3452. *-- Rev. History: 04/23/1992 -- Original Release
  3453. *-- Calls.......: None
  3454. *-- Called by...: Any
  3455. *-- Usage.......: DO ReColor WITH <cColors>
  3456. *-- Example.....: DO Recolor WITH OldColors
  3457. *-- Parameters..: cColors = a string in the form returned by 
  3458. *--                         set("ATTRIBUTE").
  3459. *-- Returns.....: None
  3460. *-- Side effects: Changes the screen colors.
  3461. *-----------------------------------------------------------------------
  3462.  
  3463.    parameters cColors
  3464.    private cThis, cNext, nAt, cLeft, nX, cAreas
  3465.  
  3466.    m->cAreas = "   NORMHIGHBORDMESSTITLBOX INFOFIEL"
  3467.    m->cLeft = m->cColors + ", "
  3468.    m->nX = 0
  3469.    do while m->nX < 8
  3470.       m->nX = m->nX + 1
  3471.       cThis = substr( m->cAreas, 4 * m->nX, 4 )
  3472.       if m->nX = 3
  3473.          m->nAt = at( "&", m->cLeft )
  3474.          m->cNext = left( m->cLeft, m->nAt - 2 )
  3475.          m->cLeft = substr( m->cLeft, m->nAt + 3 )
  3476.          SET COLOR TO , , &cNext.
  3477.       else
  3478.          m->nAt = at( ",", m->cLeft )
  3479.          m->cNext = left( m->cLeft, m->nAt - 1 )
  3480.          m->cLeft = substr( m->cLeft, m->nAt + 1 )
  3481.          SET COLOR OF &cThis. TO &cNext.
  3482.       endif
  3483.    enddo
  3484.  
  3485. RETURN
  3486. *-- EoP: ReColor
  3487.  
  3488. *-----------------------------------------------------------------------
  3489. *-- EoP: SCREEN.PRG
  3490. *-----------------------------------------------------------------------
  3491.